我正在尝试使用带有coffeescript的骨干而不是javascript:
TodoItem = Backbone.Model.extend(
toggleStatus: ->
if @.get 'status' is "incomplete"
@.set 'status': 'complete'
else
@.set 'status': 'incomplete'
@.save()
)
todoItem = new TodoItem(
description: 'I play the guitar'
status: 'incomplete'
id: 1
)
TodoView = Backbone.View.extend(
tagName: 'div'
id: "box"
className: 'red-box'
events:
"click h3": "alertStatus"
'change input': 'toggleStatus'
template:
_.template "<h3> <input type=checkbox #{ print "checked" if status is "complete"} /> <%= description %></h3>"
initialize: ->
@.model.on 'change', @.render, @
@.model.on 'destroy', @.remove, @
toggleStatus: ->
@.model.toggleStatus()
alertStatus: ->
alert('Hey you clicked the h3!')
remove: ->
@.$el.remove()
render: ->
@.$el.html @.template(@.model.toJSON())
)
todoView = new TodoView({model: todoItem})
todoView.render()
console.log todoView.el
如果我在控制台中尝试:
todoItem.set({description: 'asdfadfasdfa'});
我明白了:
ReferenceError: todoItem is not defined
另外,我无法看到我体内的div:
<div id="box" class="red-box">
<h3>
<input type="checkbox" undefined>
"I play the guitar"
</h3>
</div>
但我可以在控制台中看到这个div。
错误在哪里?
谢谢!
答案 0 :(得分:1)
CoffeeScript的一个好处是,您可以使用@foo
代替@.foo
。写的少一点,阅读的好一点。
您不必使用Backbone的.extend()
,因为CoffeeScript具有以完全兼容的方式工作的类:
class TodoView extends Backbone.View
tagName: 'div'
id: 'box' # don't do this if you have more than one TodoView on the page at once
className: 'red-box'
todoItem
未定义,因为CoffeeScript会将所有代码包装在“立即执行的函数表达式”中,从而防止将变量泄漏到全局范围(这是一件好事)。来自文档:
虽然为了清楚起见在本文档中进行了限制,但所有CoffeeScript输出都包含在一个匿名函数中:
(function(){ ... })();
此安全包装器与自动生成var
关键字相结合,使得污染非常困难意外的全局命名空间。
如果要检查局部变量,请在Chrome的调试器或Firebug中设置断点。
我担心这段代码:
_.template "... #{ print "checked" if status is "complete"} ..."
什么是print
?你在哪里定义的?就此而言,status
在哪里?你的意思是@status
?
最后,您没有看到div
的原因是您从未将其添加到DOM中。 .render()
呈现元素...但它不会自动将它插入页面。你必须自己做:
todoView.render()
$('body').append(todoView.el) # (or wherever you want it to go)