2012-04-16 105 views
5

我正在使用backbone.js来实现好友列表aka名册。我对名册收集和个人rosterEntry骨干观点如下:Backbone.js:从集合中删除项目

Slx.Roster.Views.RosterEntry = Backbone.View.extend({ 
    tagName: "li", 
    className : "rosterEntry clearfix", 
    templateSelector: '#rosterEntryTemplate', 

    initialize: function() { 
     _.bindAll(this, 'render'); 
     this.model.bind('change', this.render); 
     this.model.bind('remove', this.remove); 
     this.template = _.template($("#rosterEntryTemplate").html()); 
    }, 

    remove: function() { 
     debug.log("Called remove event on model"); 
     $(this.el).remove(); 
    }, 
    render: function() { 
     var renderedContent = this.template(this.model.toJSON()); 
     this.id = this.model.Id; 
     $(this.el).attr('id', "friendid-" + this.model.get("id")).html(renderedContent); 
     return this; 
    } 
}); 

    Slx.Roster.Views.Roster = Backbone.View.extend({ 
     el: "div#roster-container", 
     initialize: function() { 
      _.bindAll(this, 'render', 'add', 'remove'); 
      this.template = _.template($("#rosterTemplate").html()); 
      this.collection.bind('reset', this.render); 
      this.collection.bind('add', this.add); 
      this.collection.bind('remove', this.remove); 
     }, 
     add: function (rosterEntry) { 
      var view = new Slx.Roster.Views.RosterEntry(
       { 
        model: rosterEntry 
       }); 
      $(this.el).append(view.render().el); 
     }, 
     remove: function (model) { // if I ommit this then the whole collection is removed!! 
      debug.log("called remomve on collection"); 
     }, 
     render: function() { 
      var $rosterEntries, collection = this.collection; 

      $(this.el).html(this.template({})); 
      $rosterEntries = this.$('#friend-list'); 

      _.each(collection.models, function (model) { 
       var rosterEntryView = new Slx.Roster.Views.RosterEntry({ 
        model: model, 
        collection: collection 
       }); 

       $(this.el).find("ul#friend-list").append(rosterEntryView.render().el); 
      }, this); 

      return this; 
     } 
    }) 

我测试了现在用Firebug控制台,可以通过执行填充名册就好了以下内容:

collection = new Slx.Roster.Collection 
view = new Slx.Roster.Views.Roster({collection:collection}) 
collection.fetch() 

添加到收藏也能正常工作,通过执行Firebug控制台执行以下操作:

collection.add(new Slx.Roster.Model({username:"mickeymouse"})

和新的rosterEntry被添加到名册。

我的问题是collection.remove(5)从内存集合中删除,但没有更新DOM。

奇怪的是,如果我从名册视图中删除remove()函数,名单中的所有条目都将被删除。如果我在这个方法中没有任何东西而是添加一个控制台日志,它就会调用Roster和RosterEntry视图中的remove方法 - 虽然我不确定为什么,但是它们失灵了!

["Called remove event on model"] 
["called remomve on collection"] 

如果我删除从RosterEntry模型remove函数我得到这个错误:

TypeError: this.$el is undefined 
this.$el.remove(); 

我在做什么错?从集合中删除元素时,如何从元素中删除元素?

回答

2

我认为你必须在每一个事件绑定定义context一个问题。

试图改变这一点:

this.model.bind('remove', this.remove); 

对于这一点:

this.model.bind('remove', this.remove, this); 

我知道你已经尝试与bindAll来解决这个问题,但bindAll披着每次调用与所列出的方法实际对象的上下文,但如果您在其他对象 :)上调用相同方法,则此操作无法执行任何操作。

更新

我已经阅读更多..貌似bindAllbind命令的第三paramater做完全一样的。所以也许你可以使用这个或那个。

因为是不工作的model.removebindAll是因为你忘了将它添加到_.bindAll(this, 'render')行,看在你的代码。我的建议解决了这个问题,因为我说这两种方法都是一样的。

这一切都做的是确保该所列出的方法(render, remove, ...在一种情况下或this.remove的除外)的调用是要去interpretate this作为实际对象的引用。这看起来很笨,但this非常易在JS中易变

不要担心,如果你仍然与this的事情混淆,我已经处理了很长时间,仍然not completely cofindent

也许essais like this可以帮助我们。

+1

你是什么意思我有每个evenet绑定定义的问题?不知道我真的很明白什么样的行为是对你诚实的。我只是认为所有事件都必须添加到绑定。 – reach4thelasers 2012-04-16 20:49:30

+0

绑定函数的第三个参数代表什么? – reach4thelasers 2012-04-16 22:07:03

+0

这工作!谢谢!认为我已经通过阅读另一个stackoverflow帖子了解bindall是什么,但为什么没有绑定所有的工作?它似乎做同样的事情....也为什么我不需要在集合绑定语句额外的'这个'? – reach4thelasers 2012-04-17 08:04:16

-1

这两个视图的remove方法可能被调用,因为你已经绑定在模型和集合上删除。

在RosterEntry:

this.model.bind('remove', this.remove); 

在名册:

this.collection.bind('remove', this.remove); 
+0

这不是我已经得到的吗? – reach4thelasers 2012-04-16 20:51:21

0

您是否尝试过以下方法?

this.listenTo(this.model, "remove", this.remove); 

这似乎适用于我,我喜欢它的方式读得好一点。

Link to Backbone doc