CoffeeScript/Backbone/Marionette - 教程示例转换和范围问题
Posted
技术标签:
【中文标题】CoffeeScript/Backbone/Marionette - 教程示例转换和范围问题【英文标题】:CoffeeScript/Backbone/Marionette - tutorial example conversion and scoping issues 【发布时间】:2012-05-18 12:24:01 【问题描述】:我正在尝试在 CoffeeScript 中创建此示例的基本版本:http://davidsulc.com/blog/2012/04/15/a-simple-backbone-marionette-tutorial/。所有依赖项都按照我编写它们的顺序(在正文中)声明为 .coffee 文件,并且 jQuery + Underscore + Backbone + Marionette 在头部。
我有一个模特,thing.coffee
$ ->
console.log 'load model'
class Thing extends Backbone.Model
defaults:
myValue: null
initialize: ->
console.log 'new thing'
window.Thing = Thing
我的第一个问题是范围界定:如果我不声明window.Thing
,下一个文件(Things
的集合,找不到模型Thing
,等等。我做错了什么那里?
我有一个收藏,things.coffee
$ ->
console.log 'load collection'
class Things extends Backbone.Collection
model: Thing
window.Things = Things
我有一个木偶视图,thing_view.coffee
$ ->
console.log 'load composite model view'
ThingView = Backbone.Marionette.ItemView.extend(
template: '#template-thing'
tagName: 'tr'
)
window.ThingView = ThingView
我有一个木偶视图,things_view.coffee
$ ->
console.log 'load composite collection view'
ThingsView = Backbone.Marionette.CompositeView.extend(
tagName: 'table'
id: 'things'
template: '#template-things'
itemView: ThingView
appendhtml: (collectionView, itemView) ->
collectionView.$('tbody').append itemView.el
)
window.ThingsView = ThingsView
我有一个应用程序myapp.coffee
$ ->
console.log 'load app'
# Load default data
thingsCollection = new Things([
new Thing(myValue: 'uno'),
new Thing(myValue: 'dos')
])
data:
thingsCollection: thingsCollection
# Create application, specify default layouts
MyApp = new Backbone.Marionette.Application()
MyApp.addRegions singleRegion: '#content'
# On application init...
MyApp.addInitializer (data) ->
console.log 'Init application...'
thingsView = new ThingsView(collection: data.thingsCollection)
MyApp.singleRegion.show data.thingsView
# Start application
MyApp.start data
我的 html 文件如下所示:
<div id="content">
<script type="text/template" id="template-things">
<thead>
<tr class='header'>
<th>myValue</th>
</tr>
</thead>
<tbody>
</tbody>
</script>
<script type="text/template" id="template-thing">
<td><%= myValue %></td>
</script>
</div>
关注console.log
:
load model
load collection
load composite model view
composite collection view
load app
Init application...
Uncaught TypeError: Cannot call method 'render' of undefined
所以,不用说我对发生了什么感到困惑 - 我确定这里有很多问题,所以请帮忙!
【问题讨论】:
【参考方案1】:如果我不声明
window.Thing
,下一个文件(Things
的集合,找不到模型Thing
,等等。我在那里做错了什么?
CoffeeScript 编译器将每个文件包装在一个自执行函数中,因此 Thing
是包装器的本地文件,除非您通过将其放入 window
来强制将其全球化。
我认为你真正的问题就在这里:
MyApp.addInitializer (data) ->
console.log 'Init application...'
thingsView = new ThingsView(collection: data.thingsCollection)
MyApp.singleRegion.show data.thingsView
您创建一个ThingsView
并将其存储在thingsView
中。但是随后您尝试将data.thingsView
传递给MyApp.singleRegion.show
,但data.thingsView
中没有任何内容,因此当Marionette 内部的某些内容尝试传递给view.render()
时,您会收到投诉。我想你想要这个:
thingsView = new ThingsView(collection: data.thingsCollection)
MyApp.singleRegion.show thingsView
或者这个:
data.thingsView = new ThingsView(collection: data.thingsCollection)
MyApp.singleRegion.show data.thingsView
取决于这个 data
对象的全部内容。
【讨论】:
谢谢 - 我知道为什么 window 可以工作,但不确定为什么 Backbone 不自动为模型创建全局命名空间......猜猜它不会那样工作!查看您的示例,现在显然很清楚了-我认为示例中对“猫”的引用过多,而我的 js2coffee 理解丢失了:)【参考方案2】:window.Thing
是 Coffeescript 避免全局命名空间污染的副产品。解决这个问题的惯用方式是use an App
namespace。
仅在 DOM 加载时初始化您的类是 Backbone anti-pattern。如果您为类命名,那么您只需要确保以正确的顺序加载它们(项目视图在集合视图之前)并且可以立即创建它们,而不是在页面加载之后。
您能否告诉我们Uncaught TypeError
发生在哪里?
【讨论】:
以上是关于CoffeeScript/Backbone/Marionette - 教程示例转换和范围问题的主要内容,如果未能解决你的问题,请参考以下文章