Overwriting a Backbone Models Change Event

拟墨画扇 提交于 2019-12-09 16:24:00

问题


I think what I want to do is pretty simple I just don't know how to do it. I would like to fire my own event when one of my models attributes changes for the purpose of passing some data to the event handler (whether the change was an increase or decrease in value).

Basically I want my handler to do this in the view

handler: function(increased) {
   if(increased) {
      alert("the value increased")
   }
   else {
      alert("the value decreased")
   }
}

// ...

this.model.on("change:attr", this.handler, this);

回答1:


Here you go: You basically listen for change:myvar. When a change occurs you use your model's previous() to get the old value. Depending on whether it increased or decreased you fire the appropriate event. You can listen to these events as shown in the initialize().

(function($){

    window.MyModel = Backbone.Model.extend({

        initialize: function () {
            this.on('change:myvar', this.onMyVarChange);
            this.on('increased:myvar', function () {                  
                console.log('Increased');                
            });
            this.on('decreased:myvar', function () {                  
                console.log('Decreased');                
            });
        },

        onMyVarChange: function () {
            if (this.get('myvar') > this.previous('myvar')) {
                this.trigger('increased:myvar');  
            } else {
                this.trigger('decreased:myvar');
            }
        }            
    });

    window.mymodel = new MyModel({myvar: 1});
    mymodel.set({myvar: 2});
    mymodel.set({myvar: 3});
    mymodel.set({myvar: 1});

})(jQuery);​

Running the above will print "Increased", "Increased", "Decreased" to your console.




回答2:


Just look at previousAttributes()

You can then compare:

If(this.get(attr) > this.previousAttributes()[attr]){
    console.log('bigger');
} else {
    console.log('smaller');
}

If you use that in your change event handler you're all set. No need for a custom trigger or a ton of code.

EDIT

This is from my Backbone.Validators project and how I obtain the list of all attributes which have changed during the validation step:

var get_changed_attributes = function(previous, current){
    var changedAttributes = [];
    _(current).each(function(val, key){
        if(!_(previous).has(key)){
            changedAttributes.push(key);
        } else if (!_.isEqual(val, previous[key])){
            changedAttributes.push(key);
        }
    });
    return changedAttributes;
};

This requires Underscore 1.3.1 because it's using _.has. If you can't upgrade that's an easy thing to replace though. In your case you'd passing this.previousAttributes() and this.attributes




回答3:


What if you fire your own custom event after listening to the change event?

handler: function(increased) {
   this.model.trigger('my-custom-event', stuff, you, want);
},
myHandler: function(stuff, you, want){
    // Do it...
}
// ...
this.model.on("change:attr", this.handler, this);
this.model.on('my-custom-event, this.myHandler, this);


来源:https://stackoverflow.com/questions/9439531/overwriting-a-backbone-models-change-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!