为什么Backbone View不检测模型更改?

时间:2012-02-14 07:16:56

标签: javascript javascript-events backbone.js

我有以下Backbone.js模型和集合:

// Model 
lr.Event = Backbone.Model.extend({});

// Collection
lr.Events = Backbone.Collection.extend({
  model: lr.Event,
  initialize: function(models, options) {
    this.date = options.date;
  },
  url: function() {
    return '/events' + '?date=' + this.date.toString('yyyy-MM-dd');
  }  
});

与View及其子视图一起使用:

// View
lr.MapView = Backbone.View.extend({
  el: $('#wrapper'),
  initialize: function() {
    this.date = this.options.date;
    _.bindAll(this, "render", "addAllEvents", "addOneEvent", "showNextDay", "collectData");
    this.collectData();
  },
  events: {
    "click #next": "showNextDay",
  },
  collectData: function() {
    var that = this;
    if (this.collection) this.collection.reset();
    this.collection = new lr.Events([], { date : this.date });
    this.collection.fetch({
      success:  function(resp) {
        that.render();
        that.addAllEvents();
      }
    });      
  },
  showNextDay: function() {
    this.date = this.date.add(1).days();
    this.collectData();
  },
  addAllEvents: function() {
    this.collection.each(this.addOneEvent);
  },
  addOneEvent: function(e) {
    var ev = new lr.EventView({ 
      model:  e,
      parentView: this
    });
  },
  ...
});

// Sub-view
lr.EventView = Backbone.View.extend({
  initialize: function() {
    var that = this;
    this.model.bind('change', function() {
      console.log('foo');
      that.remove();
    });
  }
  ...
});

我正在尝试将子视图绑定到其关联模型的更改。所以我希望当我致电this.collection.reset()时,会调用console.log('foo')。但事实并非如此。我之前已经console.log编辑了这个集合,并且在我重置它之后,它肯定会从"什么都没有,"所以我假设我在某种程度上弄乱了子视图与模型的绑定。

有人看到错误吗?

2 个答案:

答案 0 :(得分:2)

在没有型号的情况下拨打reset()会清空收藏品,但不会更改现有型号。当模型changes的某些属性出现'更改' 事件时。调用reset()会触发集合本身的'重置' 事件(也会在您获取集合时触发);触发此操作时,您还应重置UI,创建并呈现所有子视图项(in your case, it looks like you would call render and addAllEvents when you get the reset event)

this.collection.on('reset', this.removeExistingEventViewsThenAddAllEvents, this);

现在,当事件模型的某些属性发生变化时, 点击您的变更处理程序:

this.model.bind('change', function() {
  console.log('foo');
  that.remove();
});

但是,我真的怀疑你想在模型改变时删除事件视图。更有可能的是,您希望重新呈现它,或者使用JQuery更新它的某些部分。

答案 1 :(得分:0)

collection.reset()backbone.js v0.91,第609行)仅在静默删除并可选地重新填充集合后触发reset事件。

collection.remove( model(s) );(第548行)会在每个模型上触发remove事件,因此您可以使用 collection.remove( collection.models );在每个模型上触发remove事件。