【问题标题】:Overwriting a Backbone Models Change Event覆盖主干模型更改事件
【发布时间】:2012-02-24 23:29:45
【问题描述】:

我想我想做的很简单,我只是不知道该怎么做。我想在我的模型属性之一发生更改以将一些数据传递给事件处理程序时触发我自己的事件(无论更改是增加还是减少值)。

基本上我希望我的处理程序在视图中执行此操作

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

// ...

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

【问题讨论】:

  • hmmm 也许我的问题不清楚,我想知道如何将数据传递给change:attr 处理程序,现在每当我调用@987654323 时,主干都会“自动”触发该事件@在我的模型上。
  • 你要传递什么数据?您已经可以访问该模型,并且您将知道哪个属性已更改。
  • 我需要传递更改的性质,所以我想知道 attr 值是增加还是减少。我想我可以保留旧值的缓存并比较它们,我认为这不是很干净......
  • 啊。这很容易。它已经在那里了。请参阅下面的答案。

标签: javascript events backbone.js backbone-events


【解决方案1】:

给你:你基本上听change:myvar。当发生更改时,您可以使用模型的 previous() 来获取旧值。根据它是增加还是减少,您会触发相应的事件。如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);​

运行上述命令将在您的控制台打印“Increased”、“Increased”、“Decreased”。

【讨论】:

  • 效果很好,感谢您的提醒。对于我的情况,我需要在具有附加模型的视图中检测事件。因此事件change:attribute_name 被触发,即使模型附加到视图,以及模型值从DOM 输入发生变化时。所以我必须检查this.model.get('attribute_name') 是否为null 以避免检测到视图initialize 方法中触发的事件。
【解决方案2】:

看看previousAttributes()

然后你可以比较:

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

如果您在 change 事件处理程序中使用它,您就大功告成了。无需自定义触发器或大量代码。

编辑

这是来自我的Backbone.Validators 项目以及我如何获取在验证步骤中更改的所有属性的列表:

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

这需要下划线 1.3.1,因为它使用的是 _.has。如果您无法升级,那很容易更换。在您的情况下,您将通过 this.previousAttributes()this.attributes

【讨论】:

  • 这看起来与@ggozad 想出的相似。我接受了他,因为我喜欢听this.on('changed:attr' 并在处理程序中触发自定义事件的想法。不过感谢您的帮助:)
  • @matthew 是的。这是最好的方法。这个想法是,您可以通过比较属性来通用地做到这一点,这使得在需要时更容易重用。感谢您的反馈!
【解决方案3】:

如果您在监听到 change 事件后触发自己的自定义事件怎么办?

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

【讨论】:

    猜你喜欢
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多