javascript - 在 backbone.js 中只有"reference based" 更改而不是"value based" 更改,是'change'事件

  显示原文与译文双语对照的内容
0 0

我写了一段测试代码:

var ModelHasObjectAttribute = Backbone.Model.extend({
 defaults:{
 property_value:99, 
 object_attr:{"year":"1990"}
 },
 setYear:function(year) {//function like this cannot trigger change
 var temp_object_attr = jQuery.extend({}, this.get('object_attr') );//This shallow copy is to change the reference of object_attr,
 temp_object_attr["year"] = year;//otherwise I cannot trigger 'change' event, if the value of one attribute changed but reference not changed 
 this.set( 'object_attr', temp_object_attr ); 
 },
 changeYear:function( year ) {
 console.log("before changing," + this.get('object_attr')['year']);
 this.get('object_attr')["year"] = year;
 console.log( this.get('object_attr')); 
 },
 initialize: function () {
 var classRef = this;
 this.on('change:property_value', function() {
 alert("heard property_value changing");
 });
 this.on('change:maxvalue', function() {
 alert("heard maxvalue changing"); 
 }); 
 this.on('change:object_attr', function() {
 alert('heard object_attr changing' + classRef.get('object_attr')['year']); 
 });
 } 
});
var on_instance = new ModelHasObjectAttribute ();
on_instance.set('property_value',10);
on_instance.changeYear(2015);//this line of code does not trigger default 'change' event 
on_instance.setYear(2016);//this one triggered 
console.log( on_instance.get('object_attr') );

例如如果希望在 object_attr 更改时触发 change,则必须更改存储在 object_attr 下的对象的引用。 只修改 object_attr 对象的值,不会触发 change

如何避免昂贵的浅拷贝,还可以触发更改事件?

时间: 原作者:

0 0

因为 Backbone 没有办法检测 object_attr 对象的更改,所以这种方法无法正常工作。 这不是一般的Backbone 问题,作为一般的JavaScript点- 你不能观察对象属性的变化。

使用change事件设置深层属性的最佳方法是使用像 Backbone.DeepModel 这样的插件,它重写了 set 以处理嵌套属性:

var ModelHasObjectAttribute = Backbone.Model.extend({
//... 
 setYear:function(year) { 
//triggers 'change' events
 this.set('object_attr.year', year); 
 },
//...
}

N.B 。链接是DeepModel最近的分支。 根据应用程序设置,你可能需要使用 ( 未维护) 原始版本。

原作者:
...