【问题标题】:Why Doesn't Backbone View Detect Model Changes?为什么 Backbone View 检测不到模型更改?
【发布时间】:2012-02-14 07:16:56
【问题描述】:

我有以下 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
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.loged 集合,在我重置它之后,它肯定会从“某事变为无”,所以我假设我以某种方式弄乱了子视图与模型的绑定。

有人看到错误了吗?

【问题讨论】:

    标签: javascript javascript-events backbone.js


    【解决方案1】:

    在没有模型的情况下调用 reset() 会清空集合,但不会'更改'现有模型。 'change' 事件发生在模型changes 的某些属性时。调用 reset() 确实会触发集合本身的 '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);
    

    现在,当 Event 模型的某些属性发生更改时,您点击您的更改处理程序:

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

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

    【讨论】:

    • 完全有道理。谢谢!
    【解决方案2】:

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

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

    【讨论】:

    • 主干文档说“调用 collection.reset() 而不传递任何模型作为参数将清空整个集合”。如果整个集合都被清空了,那是不是意味着所有的模型都会被删除,从而改变呢? documentcloud.github.com/backbone/#Collection-reset
    • 好吧,源代码似乎做了我上面描述的事情。也许值得向骨干团队报告错误/功能建议。
    猜你喜欢
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 2013-05-22
    • 1970-01-01
    相关资源
    最近更新 更多