3

我的应用程序的逻辑非常简单。我有获取 JSONP 的模型(数据包含年、季度和季度包含不同的键:值)。获取数据后,View 会监听 Model 的“change”事件,然后渲染数据。到现在为止还挺好。

但随后我需要监听“change:year”/“change:quarter”并根据更改使用新的 url 获取数据。但是当 "change:year"/"change:quarter" 被触发时,全局 "change" 也会被触发。

当然,如果我将使用 Collection 而不是 Model – 对我来说就是“重置”。但在这种情况下,我不能这么容易地听“change:year”——我必须再创建几个模型(对于年、季度和季度中的每个键)。但我想让应用程序保持简单。

还有其他方法吗?或者创建更多模型是不可避免的?

谢谢。

UPD:仍然需要“更改”事件,因为模型必须在获取新数据后重新渲染。

解决方案:我创建了通用控制器,它包含需要更改的属性。并在 .url() 方法中从 Controller 获取它们以修改 url。我坚持使用 Collection 的 fetch()/"reset" 通知并在“更改”时为 Controller 设置监听器。因此,当我更改“年”/“季度”时,视图会从控制器获取通知,并且当相应的集合获取时 - 它正在使用新的 url 获取。

4

2 回答 2

1

据我了解,您不希望仅接收或更改全局模型change事件-但您必须这样做。yearquarter

因此,当接收到全局更改事件时,您可以检查它是否只是yearquarter更改,并跳过正常的事件处理。像这样的东西:

this.model.bind("change", this.render, this);
this.model.bind("change:year", this.fetchSomething, this);
this.model.bind("change:quarter", this.fetchSomething, this); 

render : function(){
    var attributesExceptYearAndQuarter = _.without(this.model.attributes, ['year', 'quarter']) 
    if(this.model.changedAttributes(attributesExceptYearAndQuarter).length > 0){
         // do the rendering
    } 
}
于 2012-10-12T15:47:10.700 回答
1

您可以在模型的更改侦听器中检查更改的属性。

var MyModel=Backbone.Model.extend({
    initialize:function(){
      this.bind("change",this.changeModel);
      this.bind("change:year",this.changeYear);

   },
   changeModel:function(model,objs){
      //Checking changed attributes
      if (_.has(objs.changes,"year") || _.has(objs.changes,"quarter")) return this;

     console.log("Processing",objs.changes);
     return this;
  },
   changeYear:function(model,new_val){
    console.log("year changed.",new_val);
    return this;
  }

});


var mymodel=new MyModel();
mymodel.set("year",2012); 
mymodel.set("month",6);

如果您有一个监听模型更改事件的视图,您应该向模型添加一个不同的属性并监听此属性的更改事件,而不是模型的更改事件并在此属性更改时呈现视图。如果您的“年”和“季度”属性未在如下更改的属性中,请在 changeModel 函数中更改此属性的值并触发侦听器。

//Edit changeModel as below
changeModel:function(model,objs){
          //Checking changed attributes
          if (_.has(objs.changes,"year") || _.has(objs.changes,"quarter")) return this;

          this.set("rerender",!this.rerender); //Changing for triggering change event
         return this;
      },


//View's constructor function
initialize:function(){
   this.model.bind("change:rerender",this.render);
}
于 2012-10-12T16:12:26.640 回答