'change'骨.js干中的事件是否只有"reference based"更改而不是"value based"更改



我写了一段测试代码:

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

如何避免昂贵的浅拷贝,同时又能触发变更事件?

这种方法不起作用,因为Backbone没有办法检测到您已经更改了object_attr对象。这与其说是一个主干问题,不如说是一个一般的JavaScript问题——你(目前)还不能观察到对象属性的变化。

用change事件设置深度属性的最好方法是使用Backbone这样的插件。DeepModel,它覆盖set以使用嵌套属性:

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

注意:这个链接是DeepModel最近的一个分支。根据你的应用程序设置,你可能需要使用(未维护的)原始版本。

最新更新