以下代码中未触发“更改”事件。
var PageView = Backbone.View.extend({
el: $("body"),
initialize: function(){
this.model.on("change:loading", this.loader, this);
},
loader: function(){
if(this.model.get("loading")){
this.$el.find('.loader').fadeIn(700);
}
else
this.$el.find('.loader').fadeOut(700);
},
});
var PageModel = Backbone.Model.extend({
defaults: {
loading: null,
},
initialize: function(){
this.set({loading:false});
},
});
$(function(){
var pageModel = new PageModel({});
var pageView = new PageView({model: pageModel});
})
如果我在模型的initialize
函数中添加它,它会起作用:
setTimeout(function() {
this.set({'loading': 'false'});
}, 0);
我可以这样离开,但这是一个错误。
答案 0 :(得分:2)
这是代码运行的顺序:
initialize
函数,将loading
属性设置为false
,"change:loading"
永远不会调用事件处理程序,因为事件在注册后永远不会发生。
首先从模型中删除集合。
var PageModel = Backbone.Model.extend({
defaults: {
loading: null
}
});
然后,在创建视图后,设置loading
属性。
var pageModel = new PageModel();
var pageView = new PageView({ model: pageModel });
pageModel.set('loading', false); // now the event should trigger
由于在模型的loading
属性发生更改之前现在已注册了侦听器,因此将调用事件处理程序。
使用Backbone的最佳做法:
.listenTo
over .on
以避免内存泄漏el
property on the view 视图是一个原子组件,应该只关心自身及其子视图。
虽然在您的情况下,在视图上使用el
属性并不重要,但它仍然超出了视图的职责范围。让调用代码处理传递元素以用于此视图。
var PageView = Backbone.View.extend({
initialize: function() {
this.model = new PageModel();
this.$loader = this.$('.loader');
this.listenTo(this.model, "change:loading", this.loader);
},
loader: function() {
this.$loader[this.model.get("loading")? 'fadeIn': 'fadeOut'](700);
},
render: function() {
this.loader();
return this;
}
});
将默认值放在它们所属的位置。
var PageModel = Backbone.Model.extend({
defaults: {
loading: false
}
});
我们选择body
作为要用于视图的元素,使用el
选项,然后在准备好时调用render
。
$(function() {
var pageView = new PageView({ el: 'body' }).render();
});
事件不会立即由侦听器触发,而是使用render
函数将视图置于其默认状态。然后,loading
属性的任何后续更改都将触发回调。
我在个人资料页面上列出了most useful answers I've written about Backbone。您应该看看,它从开始到高级,甚至提供了一些聪明的Backbone组件,可以解决常见问题(例如在视图外部检测 )。