最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Overwriting a Backbone Models Change Event - Stack Overflow

programmeradmin3浏览0评论

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);

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);
Share Improve this question asked Feb 24, 2012 at 23:29 MatthewMatthew 13.3k6 gold badges43 silver badges45 bronze badges 4
  • hmmm maybe my question is not clear, I want to know how I can pass data to the change:attr handler, right now that event is being fired "automagically" by backbone, whenever I call set() on my model. – Matthew Commented Feb 25, 2012 at 0:17
  • What data do you want to pass? You'll have access to the model already and you'll know which attribute has been changed. – tkone Commented Feb 25, 2012 at 0:25
  • I need to pass the nature of the change, so if the attr value increased vs decreased i want to know. I guess I can keep a cache of the old value and pare them, I don't think this is very clean... – Matthew Commented Feb 25, 2012 at 2:32
  • 1 Ah. That is easy. It's already there. See my answer below. – tkone Commented Feb 25, 2012 at 12:04
Add a ment  | 

3 Answers 3

Reset to default 12

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.

Just look at previousAttributes()

You can then pare:

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

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);
发布评论

评论列表(0)

  1. 暂无评论