集合在两个独立的集合上添加事件触发器

时间:2011-06-01 23:33:46

标签: javascript backbone.js

试图通过添加一些额外的功能来理解backbone.js(Todos App)框架的内部,我的Todos App在两个集合上触发了一个collection.add事件,原始的TodoList和我自己的UnsavedList

这就是我所做的:

通过_.template添加“全部完成标记”按钮,检查所有未选中的复选框,而不保存对服务器的更改。

通过_.template添加'保存({unsaved collection length})'按钮到文档。

为实现这一目标,我会跟踪TodoList中所有模型的'savedState'

// inside TodoList
hasUnsaved: function() {
  return this.filter(function(todo) {
    var isEqual = _.isEqual(todo.savedAttributes, todo.attributes);
    return !isEqual;
  })
},

声明并实例化UnsavedList:

// inside window
window.UnsavedList = Backbone.Collection.extend({

  model: Todo,

  initialize: function() {
      this.bind('add', this.addHandler)
  },

  addHandler: function() {
      alert('added')
  }
});

window.UnsavedTodos = new UnsavedList;

与原始示例一样,add事件绑定到addOne Handler。

// inside AppView
...
initialize: function() {
  Todos.bind('add', this.addOne);
  ...
}

收听'Mark All Done'按钮点击调用markAllDone,然后触发'change:allDone':

// inside AppView
markAllDone: function() {
    Todos.each(function(todo) {
        todo.set({ done: true });
    })
    Todos.trigger('change:allDone');

},

...和'change:allDone'调用:

// inside AppView
checkSaved: function() {
    this.$('#todo-controls #button-saved').html(this.buttonSavedTemplate({
        saved: function() {
            var list = Todos.hasUnsaved();
            _.each(list, function(todo) {
                UnsavedTodos.add(todo);
            })
            return list.length;
        }
    }));
},

如果查看模板对象的迭代器,我将所有未保存的模型添加到我的UnsavedList中。但奇怪的是,TodoList还会在所有未保存的模型显示在页面上的重复内容中收听这个确切的“添加”事件。

为什么这样,甚至很难我'仅'添加'到UnsavedList。

想法?

1 个答案:

答案 0 :(得分:0)

即使我可以使用{silent:true}选项,但我对此行为过于好奇并且发现自己在查找源代码:

每次将模型添加到集合时,模型本身都会触发add-event。在我的情况下,TodoList和UnsavedList都在监听'add'

这是从backbone.js剪下的代码:

// inside _add
if (!options.silent) model.trigger('add', model, this, options);

为了解决这个问题(猜测我想保持我的事件流程),我只是存储模型的克隆副本:

UnsavedTodos.add(_.clone(todo), { silent: false });

我确信使用嵌套集合或处理相同模型而不是克隆的任何事情来实现这一点要容易得多,我通过事件跟踪我未保存(克隆)的模型,每次在保存后触发,创建或毁灭。

This is my completed modified Todos App