解析 Backbone.js 中的模型 - 使用 {silent:true} 调用集并触发属性更改事件?
我有一个这样的图表模型:
//PSEUDO
chartModel = Backbone.Model.extend({
defaults: {
year : 1970,
selected = ["Sweden", "Denmark"]
}
}
我现在想设置年份和年份。 selected:
chartModel.set({year: 1987, selected : ["Finland"]})
但在触发模型更改之前,我想“解决”对此不稳定模型的更改。因此,我传递silent:true并覆盖set方法:
chartModel.set({year: 1987, selected : ["Finland"]}, {silent:true})
//Pseudo set override
set : function(attrs, options) {
// Extract attributes and options.
options || (options = {});
if (!attrs) return this;
if (attrs.attributes) attrs = attrs.attributes;
var now = this.attributes, escaped = this._escapedAttributes;
[...]
datamanager.loadNewDataIfNeeded(oldModel, newModel, callback)
我特别希望数据管理器在触发更改事件之前“区分”旧属性与新属性:
callback : function(){
chartModel.change();
}
现在 - 当我知道正确的数据已就位时 -我想要渲染视图。
...但是我的侧边栏视图必然会发生变化:selected 不会呈现?
Sidebar = Backbone.View.extend({
initialize: function(){
this.model.bind("change:selected", this.render);
}
render : [...]
});
我的问题:
手动触发 model.change() 时,为什么没有触发各个属性更改事件?
我真的需要重写模型设置方法来实现我想要的(“当多个属性同时更改时解析模型”)还是有更好的方法?
I have a chart model like this:
//PSEUDO
chartModel = Backbone.Model.extend({
defaults: {
year : 1970,
selected = ["Sweden", "Denmark"]
}
}
I'd now like to set both year & selected:
chartModel.set({year: 1987, selected : ["Finland"]})
But before I trigger the model change I'd like to "resolve" the changes to this unstable model. So I pass silent:true and override the set method:
chartModel.set({year: 1987, selected : ["Finland"]}, {silent:true})
//Pseudo set override
set : function(attrs, options) {
// Extract attributes and options.
options || (options = {});
if (!attrs) return this;
if (attrs.attributes) attrs = attrs.attributes;
var now = this.attributes, escaped = this._escapedAttributes;
[...]
datamanager.loadNewDataIfNeeded(oldModel, newModel, callback)
I'd specifically like a data manager to "diff" the old attributes vs the new before I trigger the change event:
callback : function(){
chartModel.change();
}
Now - when I know that the right data is in place - I'd like the views to render.
... But my Sidebar view that is bound to change:selected does not render?
Sidebar = Backbone.View.extend({
initialize: function(){
this.model.bind("change:selected", this.render);
}
render : [...]
});
My questions:
When triggering model.change() manually, why aren't the individual attribute change events fired?
Do I really need to override the model set method to achieve what I want to ("resolving the model when several attributes are changed at once") or is there a better method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据我对您想要做的事情的理解,我的观点是:
很少或从不重写 set 方法;不知道为什么你觉得在这种情况下必须这样做。
如果您在没有 {silent: true} 的情况下调用 set 方法,您应该获得change:year 和change:selected 和change 的事件。但必须将对象绑定到它们才能获取它们。请参阅bind 函数。
如果调用change函数,则只会触发change事件。不会触发属性级别事件。
听起来您不应该重写 set 方法,而只需确保您在对此模型的更改感兴趣的那些对象中具有正确的绑定即可。另外,消除沉默:真实的段落。
这是根据您的评论编写的一些代码:
});
其中模型本身绑定 a 和 b 属性的更改事件,并通过检查是否可以计算 c 来处理这些事件,然后执行此操作,然后根据 Ajax 返回设置 c 的值。然后模型将触发“change:c”以观察视图。我在视图管道中绘制了草图,这将实现这一点。
这是未经测试的代码,但希望在概念上接近。
My opinion based upon my understanding of what you are trying to do is this:
Rarely or never override the set method; not sure why you feel you have to do it in this case.
If you call the set method without {silent: true}, you should get events for change:year and change:selected and change. But objects have to be bound to them to get them. See the bind function.
If you call the change function, only the change event is triggered. The attribute level events are not triggered.
It sounds like you should not be overriding the set method and just assure that you have proper binding in those objects that have an interest in this model's changes. Also, eliminate the silent: true passage.
Here's some code based upon your comment:
});
where the model itself is binding to change events for the a and b attributes and handling those by checking to see if it can calculate c, then doing so, then setting the value of c based upon the Ajax return. The model will then trigger 'change:c' for a view to observe. I sketched in the view plumbing which would enable this.
This is untested code, but hopefully conceptually close.