我可能在这里遗漏了一些微不足道的东西,但看起来setElement没有重新绑定事件,尽管文档和代码都说它应该。
我尝试用尽可能少的代码重新创建问题,但它仍然相当多,所以我在Gist上发布了它:
https://gist.github.com/gooli/baecc277d864e28eb2c7
当我单击其中一个复选框时,控制台上将显示“selected”。但是当我再次点击它时,它不会再输入事件。
我这样做是因为我真的希望模板包含<tr>
元素而不仅仅是内部<td>
元素。
当我删除<tr>
元素,在视图中使用tagName: 'tr'
并使用通用this.$el.html(...)
公式进行渲染时,工作正常。
我错过了什么?
答案 0 :(得分:2)
根据jakee的回答,我提出了一个更好的解决方案,不需要在render
内重新实现模板逻辑。
window.DayView = Backbone.View.extend({
template: Handlebars.compile($('#day-template').html()),
events: {
'click .select input': 'select'
},
initialize: function () {
this.model.bind('change', this.render, this);
this.setElement(this.template(this.model.toJSON()));
},
render: function() {
console.log('render');
this.$el.html($(this.template(this.model.toJSON())).html());
return this;
},
select: function (event) {
console.log('selected');
this.model.set({selected:$(event.target).is(':checked')});
}
});
initialize
方法使用整个模板来创建元素。 render
方法仅使用模板的内部html来呈现新值。
这看起来很干净,允许我在模板中定义所有视图的HTML而不依赖tagName
。我是一个快乐的露营者。
答案 1 :(得分:1)
出于多种原因,您的方法存在问题。
this.model.each(function(day) {
that.$el.append(new DayView({model:day}).render().$el);
});
您可以在此处将DayView
元素附加到DayListView
。您将每个视图的$el
附加到父视图的$el
。当子元素具有固定的包装元素时,这是标准的。这是您定义tagName
属性的情况。但是当你不断重新分配视图的元素时,这是有问题的。
undelegateEvents
$el
和el
填充了新模板delegateEvents
醇>
现在导致问题的原因是:
我的解决方案是:
window.DayView = Backbone.View.extend({
template: Handlebars.compile($('#day-template').html()),
events: {
'click .select input': 'select'
},
initialize: function () {
this.model.bind('change', this.render, this);
this.setElement(this.template(this.model.toJSON()));
},
render: function() {
this.$el.find('.name').text(this.model.get('name'));
this.$el.find('.select input').attr('checked', this.model.get('selected'));
return this;
},
select: function (event) {
this.model.set({selected:$(event.target).is(':checked')});
}
});
这样,每次单击复选框时都不会替换视图元素。现在这个解决方案很可能远非最佳,但应该指向正确的方向。
希望这有帮助!