我有一个使用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错误。
未捕获的TypeError:无法读取属性&#39; on&#39;第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 Objects添加任务时需要实例化此模型。只要我在模型中添加或删除新的Task项,就应该初始化它。我不太明白这会如何引发异常。
顺便说一句,我是Backbone.js和Underscore.js的新手。我只是按照在线教程了解这些框架是如何工作的......
感谢。
答案 0 :(得分:0)
您没有将任何模型绑定到您的视图。您可以在实例化新视图时传递模型和/或集合。这些属性将自动绑定到您视图的this.model
/ this.collection
。
您没有传递模型,因此在您的视图中未定义this.model
。您应该传递空的任务列表,以便在以后填充时,onchange
将被触发,您的视图将会重新呈现。
new TasksView({model: new Tasks()});