Backbone下划线击中集合中的所有项目

时间:2012-10-20 18:28:47

标签: javascript backbone.js underscore.js

我是骨干和下划线的新手。首先让我说我已经阅读了所有在线示例,但我仍然遗漏了一些东西。

发生的事情是我正在加载我的对象列表,但是当我点击删除它时会通过所有对象。我知道这是因为我没有正确分配单个项目,但我看不出是什么导致了这个问题。

我会喜欢一些帮助。

这是基本的HTML代码

<div id="itemid" class="view">            
      <span class="text">{{-text}}</span>
      <a id="dele" data-role="button" data-inline="true" data-icon='delete' >Delete</a>
</div>

这是我的项目列表代码

bb.view.List = Backbone.View.extend(_.extend({    
  tagName: "ul",

  initialize: function( items ) {
          var self = this
      _.bindAll(self)

      self.setElement('#itemid')

      self.elem = {
         text: self.$el.find('#text')
      }
      self.items = items

  },

      render: function(items) {
      var self = this

      self.$el.empty()

      self.items.each(function(item){
          var itemview = new bb.view.Item({
              model: item
          })
          itemview.render()
      })
  }

},scrollContent))

现在最后是各个项目的项目视图,请注意下面的模板代码。

bb.view.Item = Backbone.View.extend(_.extend({  
  tagName: "li",
  events: {
      'tap #dele': function(){ 
        var self = this
       self.removed()      
        return false;
      }  
  },  

    render: function(){
        var self = this
        _.bindAll(this)
        self.setElement('#itemid')

        self.elem = {
        dele: self.$el.find('#dele')
        }       

        var html = self.tm.item( self.model.toJSON() )
        $(this.el).append( html )  

    },

    removed: function()
    {
        var self = this
        this.model.removed();
    }
},{
    tm: {
      item: _.template( $('#itemid').html() )
    }
}))

希望有人可以提供帮助

标记

1 个答案:

答案 0 :(得分:0)

我知道这与你的问题没有直接关系,但我有几点建议。你的代码:

您似乎到处都使用var self = this; self.method()。除非您需要将this传递给闭包,否则不要这样做。但是,是的,当你进入each迭代器时,你需要它。

您无需在所有方法上调用_.bindAll(self)。同样,最好明确地将this绑定到方法,例如:

this.collection.bind('reset', this.render, this);
this.el.on('click', 'a', this.handleClick.bind(this));

您可能没有意识到,甚至可能甚至不关心您的客户端资源,但是将您的环境绑定到this会产生许多您永远不会使用的闭包(分配内存)。

现在有了您的问题,我会按如下方式重构您的代码:

var itemTmp = $('#itemid').html();

bb.view.Item = Backbone.View.extend({  
    tagName: "li",

    events: {
        'tap #dele': "deleteItem"
    },

    render: function(){
        this.el = _.template(itemTmp)(this.model.toJSON());
    },

    deleteItem: function() {
        this.model.destroy(); // deletes model
        this.remove(); // deletes view
    }
});


bb.view.List = Backbone.View.extend({    
    tagName: "ul",

    initialize: function(items) {
        this.setElement('#itemid');
        this.collection = items;
        this.render();
    },

    render: function() {
        var self = this; // yes, you will need it in the iterator

        this.$el.empty();

        this.collection.each(function(model){
            var itemview = new bb.view.Item({
                model: model
            });

            itemview.render();
            self.$el.append(itemview.el);
        });
    }

});

_.extend(bb.view.List.prototype, scrollContent);

请注意,Item视图不会将其HTML插入DOM(或父视图元素)。基本上,当子视图或依赖项不访问父元素时,这是一种更好的做法。因此,您可以render()返回HTML,也可以从实例化的模块中访问View的实例el属性。

上次观察 - 当您拥有一个包含大量视图的应用时,您不希望为每个列表项创建新的View实例。您最好插入具有唯一ID的DOM节点,然后在DOM事件上读取这些ID并解析项ID,并按this.collection.get(id)查找项目。但同样,这是出于纯粹的性能考虑。