Backbone listenTo 不会因 属性 更改而触发
Backbone listenTo does not fire for property change
我是 Backbone 的新手,我有一些代码可以监听 属性 的变化并触发一个函数。我在网上看到的关于如何使用 listenTo 的所有内容似乎都涵盖了这种情况,所以我不知道我忽略了什么。
为了更好地理解我做了一个简单得多的示例,它只包含一个模型、一个视图和设置 listenTo。问题仍然出现在那个较小的样本中。
我已经放入了一些代码来记录正在触发哪些函数以及触发顺序。当我看到 运行 时,这段代码几乎是我期望的顺序,除了永远不会调用 onSomethingChanged。
var AppView = Backbone.View.extend({
initialize: function(){
this.listenTo(this.model, 'change:hasName', this.onSomethingChanged);
$('#steps').append('<li>AppView initialize</li>');
this.model.setName('Test Name');
},
onSomethingChanged: function(){
$('#steps').append('<li>AppView onSomethingChanged</li>');
}
});
var SomeModel = Backbone.Model.extend({
initialize: function(){
this.bind('change:name', this.onNameChanged, this);
this.set({'name': 'Nothing'});
$('#steps').append('<li>SomeModel initialize</li>');
},
onNameChanged: function(status, name){
this.set({'hasName': name != null});
$('#steps').append('<li>SomeModel onNameChanged</li>');
},
setName: function(name){
this.set({'name': name});
$('#steps').append('<li>SomeModel setName</li>');
}
});
$(function(){
window.app = new AppView({model: new SomeModel()});
});
我在此处的 fiddle 中进行了设置:https://jsfiddle.net/hamveefz,它显示的顺序如下:
- SomeModel onNameChanged
- SomeModel 初始化
- AppView 初始化
- SomeModel onNameChanged
- SomeModel setName
我假设在 SomeModel 的 onNameChanged 函数中,它随后对 hasName 属性 执行 'this.set' 会自动导致调用 hasName 更改的侦听器。
有人可以向我解释我哪里出错了吗?
调用 set
不一定会改变任何东西。例如,这个:
model.set('property', model.get('property'));
不会触发 'change'
事件,因为它实际上没有做任何事情。
您的模型的 initialize
设置名称:
this.set({'name': 'Nothing'});
'change:name'
处理程序受该点约束,因此 onNameChanged
将被调用并且 hasName
将设置为 true
。
然后构建视图,其 initialize
将:
this.listenTo(this.model, 'change:hasName', this.onSomethingChanged);
this.model.setName('Test Name');
您认为 setName
应该触发 'change:hasName'
事件,但它不会。 hasName
属性此时已经是 true
并且您将执行 set('hasName', true)
所以它不会改变。
您最好将 name
保留为 null
或 undefined
,直到它真正被设置为止。您将从模型的 initialize
中删除 this.set({'name': 'Nothing'});
并添加:
defaults: {
name: null,
hasName: false
}
然后调整视图(及其模板)来处理 "no name" 案例。
我是 Backbone 的新手,我有一些代码可以监听 属性 的变化并触发一个函数。我在网上看到的关于如何使用 listenTo 的所有内容似乎都涵盖了这种情况,所以我不知道我忽略了什么。
为了更好地理解我做了一个简单得多的示例,它只包含一个模型、一个视图和设置 listenTo。问题仍然出现在那个较小的样本中。
我已经放入了一些代码来记录正在触发哪些函数以及触发顺序。当我看到 运行 时,这段代码几乎是我期望的顺序,除了永远不会调用 onSomethingChanged。
var AppView = Backbone.View.extend({
initialize: function(){
this.listenTo(this.model, 'change:hasName', this.onSomethingChanged);
$('#steps').append('<li>AppView initialize</li>');
this.model.setName('Test Name');
},
onSomethingChanged: function(){
$('#steps').append('<li>AppView onSomethingChanged</li>');
}
});
var SomeModel = Backbone.Model.extend({
initialize: function(){
this.bind('change:name', this.onNameChanged, this);
this.set({'name': 'Nothing'});
$('#steps').append('<li>SomeModel initialize</li>');
},
onNameChanged: function(status, name){
this.set({'hasName': name != null});
$('#steps').append('<li>SomeModel onNameChanged</li>');
},
setName: function(name){
this.set({'name': name});
$('#steps').append('<li>SomeModel setName</li>');
}
});
$(function(){
window.app = new AppView({model: new SomeModel()});
});
我在此处的 fiddle 中进行了设置:https://jsfiddle.net/hamveefz,它显示的顺序如下:
- SomeModel onNameChanged
- SomeModel 初始化
- AppView 初始化
- SomeModel onNameChanged
- SomeModel setName
我假设在 SomeModel 的 onNameChanged 函数中,它随后对 hasName 属性 执行 'this.set' 会自动导致调用 hasName 更改的侦听器。
有人可以向我解释我哪里出错了吗?
调用 set
不一定会改变任何东西。例如,这个:
model.set('property', model.get('property'));
不会触发 'change'
事件,因为它实际上没有做任何事情。
您的模型的 initialize
设置名称:
this.set({'name': 'Nothing'});
'change:name'
处理程序受该点约束,因此 onNameChanged
将被调用并且 hasName
将设置为 true
。
然后构建视图,其 initialize
将:
this.listenTo(this.model, 'change:hasName', this.onSomethingChanged);
this.model.setName('Test Name');
您认为 setName
应该触发 'change:hasName'
事件,但它不会。 hasName
属性此时已经是 true
并且您将执行 set('hasName', true)
所以它不会改变。
您最好将 name
保留为 null
或 undefined
,直到它真正被设置为止。您将从模型的 initialize
中删除 this.set({'name': 'Nothing'});
并添加:
defaults: {
name: null,
hasName: false
}
然后调整视图(及其模板)来处理 "no name" 案例。