【问题标题】:backbone view not filtered on initialize初始化时未过滤主干视图
【发布时间】:2013-08-19 17:20:36
【问题描述】:

正如您在以下代码中看到的那样,我正在尝试使用从集合中获取和过滤的数据来初始化主干视图。此过滤器不起作用并返回所有项目:

app.ShopView = Backbone.View.extend({
el:$('#content'),

initialize: function(options) { 
var that = this;
this.collection = new app.ShopProductsCollection();
this.collection.fetch().done(function(){
        var filterType = _.filter(that.collection.models,function(item){            
            return item.get('category') === 'accessories';
        })
        that.collection.reset(filterType);
    });
this.listenTo(this.collection, 'add', this.addOne);
},

render: function() {
this.$el.html(this.template());
this.addAll();
return this;
},

addAll: function() { 
this.collection.each(this.addOne, this);

},

addOne: function(model) {
view = new app.ShopItemView({model: model}); 
view.render();
this.$el.append(view.el);
model.on('remove', view.remove, view);
}

});

使用 JQuery $.when() 包装器和重置事件的侦听器来调用渲染方法,这是我的新初始化方法:

initialize: function(options) { 
var that = this;
this.collection = new directory.ShopProductsCollection();
$.when(this.collection.fetch()).done(function(){
var filterType = _.filter(that.collection.models,function(item){            
        return item.get('category') === 'accessories';
    })
that.collection.reset(filterType);
     });
this.listenTo(this.collection, 'reset', this.render);
this.listenTo(this.collection, 'add', this.addOne);
},

【问题讨论】:

    标签: backbone.js underscore.js


    【解决方案1】:

    对于使用主干过滤集合,最好的方法是获取集合并返回一个子集过滤集合,这也将使您的代码更具可重用性

    要制作过滤器,您应该具有过滤功能

    var app.ShopProductsCollection = Backbone.Collection.extend ({
      filtered : function () { 
    

    我建议使用 UnderScore 过滤器,它将返回 true 表示有效,false 表示无效,其中 true 是您要查找的内容。使用 this.models 获取当前集合模型 使用 model.get( '' ) 获取要检查的元素

        var results = _.filter( this.models, function ( model ) {           
            if ( item.get('category') === 'accessories' ) 
            return true ; 
            return false ;
        });
    

    然后使用下划线映射您的结果并将其转换为 JSON 之类的

        results = _.map( results, function( model ) { return model.toJSON()  } );
    

    最后返回一个只有结果的新主干集合

        return new Backbone.Collection( results ) ;
    

    如果您不想保留集合中的所有数据而只保留过滤后的数据,则可以选择重置集合并跳过上面的返回,如

        this.reset( results ) ;  
    

    在您的视图中在获取集合后调用过滤器函数并呈现过滤后的集合结果

            var filteredCollection = this.collection.filtered() ;
            this.collection = filteredcollection ; 
            this.render() ;
    

    【讨论】:

      【解决方案2】:

      我首先看到了几个问题,

      el: '#content' instead el:$('#content'),
      

      选择器会自动转换成jquery选择器

      this.collection.fetch({success: ....}) or jquery promise for done or jquery $.when for done method, instead this.collection.fetch().done 
      

      ...提示...木偶可以帮到你 + coffeescript 也很强大.. 这是重写的例子....

      class app.ShopView extends Backbone.View
      
        el: "#content"
      
        initialize: (opt) ->
           @collection = new app.ShopProductsCollection
           @collection.fetch(success: _.bind(@onCollectionFetch, @))
           @collection.on 'add', @addOne
      
      
        onCollectionFetch: (collection) ->
           filter = _.filter collection.models, (model) ->
             model.get('category') is 'accessories'
           collection.reset filter 
      
      
        render: ->
          @$el.html @template()
          @addAll()
          @
      
      
        addAll: () ->  
          @collection.each @addOne, @
      
      
        addOne: (model) ->
          view = new app.ShopItemView model: model  
          view.render()
          @$el.append view.el
          model.on 'remove', view.remove, view
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-23
        • 1970-01-01
        • 1970-01-01
        • 2012-11-13
        • 1970-01-01
        相关资源
        最近更新 更多