尝试创建一个todo示例应用程序来搞乱骨干。我无法弄清楚为什么任务复选框的click事件没有触发。这是我的TaskCollection,TaskView和TaskListView的代码:
$(document).ready(function() {
Task = Backbone.Model.extend({});
TaskCollection = Backbone.Collection.extend({
model: 'Task'
});
TaskView = Backbone.View.extend({
tagName: "li",
className: "task",
template: $("#task-template").html(),
initialize: function(options) {
if(options.model) {
this.model = options.model
}
this.model.bind('change',this.render,this);
this.render();
},
events: {
"click .task-complete" : "toggleComplete"
},
render: function(){
model_data = this.model.toJSON();
return $(_.template(this.template, model_data));
},
toggleComplete: function() {
//not calling this function
console.log("toggling task completeness");
}
});
TaskListView = Backbone.View.extend({
el: $("#task-list"),
task_views: [],
initialize: function(options) {
task_collection.bind('add',this.addTask,this);
},
addTask: function(task){
task_li = new TaskView({'model' : task});
this.el.append(task_li.render());
this.task_views.push(task_li);
},
});
});
任务模板:
<script type='text/template' id='task-template'>
<li class="task">
<input type='checkbox' title='mark complete' class='task-check' />
<span class='task-name'><%= name %></span>
</li>
</script>
我似乎无法弄清楚为什么toggleComplete
事件不会触发任务。我该如何解决这个问题?
答案 0 :(得分:2)
这里的问题是,在创建新视图时,骨干事件仅设置为视图元素(this.el
)。但在您的情况下,元素不使用。因此,您的视图中包含tagName:li
属性,这会让主干创建一个新的li
元素,但您不会使用它。您返回的是从模板创建的新列表元素,但不是元素主干创建的,您可以通过this.el
因此,您必须手动将事件添加到模板使用jQuery创建的元素中,或将模板作为innerHtml添加到元素中:
(this.el.html($(_.template(this.template, model_data)))
答案 1 :(得分:0)
尝试使用.bind()更改设置侦听器的行以使用.live()。当您想要将侦听器绑定到将在页面加载后创建的元素时,应使用.live()。
最新版本的jQuery消除了这一点丑陋,并简化了用于设置事件监听器的方法。
答案 2 :(得分:0)
您的活动与.task-complete
课程绑定,但您的复选框上的课程为.task-check
答案 3 :(得分:0)
尝试修改渲染函数以调用delegateEvents(),如下所示:
render: function(){
model_data = this.model.toJSON();
this.el = $(_.template(this.template, model_data));
this.delegateEvents();
return this.el;
},
你最好不要将模板更改为不包含li然后返回this.el而不是替换它,但是如果你想要事件工作,你需要将this.el作为根元素单向或其他; delegateEvents()重新附加事件的东西,所以当你改变this.el应该解决这个问题。
答案 4 :(得分:0)
@AndreasKöberle正确回答。您需要为this.el
指定一些内容以使事件有效。
我更改了您的模板和TaskView#render()
功能。
此JSFiddle已应用更改。
新渲染功能:
render: function(){
var model_data = this.model.toJSON();
var rendered_data = _.template(this.template, model_data);
$(this.el).html(rendered_data);
return this;
}
建议render()
返回此内容。
TaskListView#addTask函数中的一行从this.el.append(task_li.render());
更改为this.el.append(task_li.render().el);
。
模板更改
由于我们在render()函数中使用this.el
,因此我们必须从模板中删除<li>
标记。
<script type='text/template' id='task-template'>
<input type='checkbox' title='mark complete' class='task-complete' />
<span class='task-name'><%= name %></span>
</script>