【发布时间】:2014-07-12 11:37:13
【问题描述】:
我有一个使用 Backbone 框架的非常简单的 ToDo List 应用程序。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>To do List</title>
<style>
.completed{
text-decoration: line-through;
color: #666;
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script type="text/javascript" src="js/underscore.js"></script>
<script type="text/javascript" src="js/backbone.js"></script>
</head>
<body>
<h1>My Todos</h1>
<div id="tasks">
<button class="add">Add Task</button>
<button class="clear hide">Clear All</button>
<ul></ul>
</div>
<script id="taskTemplate" type="text/template">
<span class="<%= completed ? 'completed' : 'incomplete' %>"><%= text %></span>
<button class="complete"></button>
<button class="delete"></button>
</script>
<script type="text/javascript">
var Task = Backbone.Model.extend({
defaults: {text: 'New task', completed: false}
});
var Tasks = Backbone.Collection.extend({
model: Task,
el: '#tasks',
initialize: function(){
this.collection = new Tasks;
this.collection.on('add', this.appendNewTask, this);
this.items = this.$el.children('ul');
},
add: function(){
var text = prompt('What do you need to do?');
var task = new Task({text: text});
this.collection.add(task);
},
appendNewTask: function(task){
var TasksView = new TasksView({model:task});
this.items.append(TasksView.el);
},
completed: function(){
return _.filter(this.models, function(model){
return model.get('completed');
});
}
});
var TasksView = Backbone.View.extend({
tagName: 'li',
el: '#tasks',
template: _.template($('#taskTemplate').html()),
initialize: function(){
this.model.on('change', this.render, this);
this.model.on('remove', this.unrender, this);
this.render();
},
render: function(){
var markup = this.template(this.model.toJSON());
this.$el.html(markup);
},
unrender: function(){
this.$el.remove();
},
events: {
'click .add': 'add',
'click .clear': 'clearCompleted',
'click .delete': 'delete',
'click .complete': 'updateStatus',
'dblclick span': 'edit'
},
add: function(){
var text = prompt('What do you need to do?');
var task = new Task({text: text});
},
delete: function(){
this.model.destroy();
this.$el.remove();
},
updateStatus: function(){
this.model.set('completed', !this.model.get('completed'));
},
edit: function(){
var text = prompt('What should we change your task to?', this.model.get('text'))
this.model.set('text',text);
},
clearCompleted: function(){
var completedTasks = this.collection.completed();
this.collection.remove(completedTasks);
}
});
new TasksView;
</script>
<!-- Template JS -->
</body>
</html>
当我访问并加载页面时,我可以在控制台日志中看到一个未捕获的 javascript 错误。
Uncaught TypeError: Cannot read property 'on' of undefined 在第 78 行。
在指示的行号处查看代码,它指向了这个
var TasksView = Backbone.View.extend({
//.....
initialize: function(){
this.model.on('change', this.render, this); // this is the line the console is complaining
this.model.on('remove', this.unrender, this);
this.render();
},
//.....
});
在接下来的几个小时盯着这个并分析了代码之后,我无法弄清楚为什么在没有任务添加到 TaskView 对象的情况下需要实例化这个模型。当我在模型中添加或删除一个新的任务项时,它应该被初始化。我不太明白这会如何引发异常。
顺便说一句,我是 Backbone.js 和 Underscore.js 的新手。我只是按照在线教程来了解这些框架是如何工作的......
谢谢。
【问题讨论】:
标签: javascript backbone.js underscore.js