1

我对Backbone比​​较陌生,虽然我知道如何使用它的一般想法,但我的学习速度很快,而且我可能错过了一些关键元素。如何在过滤后使用原始Backbone集合?

所以我有一个集合,它包含一个叫做“type”的属性,它可以是文章,书,视频,类。我有视图渲染和一切,但我需要能够在点击链接时过滤集合。

我的问题是 - 我怎样才能得到它来过滤集合,并仍然能够重新过滤原始集合,当我点击另一种类型?

这里是我的代码的要点,我简化它,为方便阅读:

var TagsView = Backbone.View.extend({ 
    initialize: function(query) { 
     this.collection = new TagsCollection([], {query: self.apiQuery}); 
     this.collection.on('sync', function() { 
      self.render(); 
     }); 
     this.collection.on('reset', this.render, this); 
    }, 
    render: function() { 
     //renders the template just fine 
    }, 
    filter: function() { 
     //filtered does work correctly the first time I click on it but not the second. 
     var filtered = this.collection.where({'type':filter}); 
     this.collection.reset(filtered); 
    } 
}); 

更新:我设法得到这个工作。我结束了触发过滤器事件。

var TagsCollection = Backbone.Collection.extend({ 
    initialize: function(model, options) { 
     this.query = options.query; 
     this.fetch(); 
    }, 
    url: function() { 
     return '/api/assets?tag=' + this.query; 
    }, 
    filterBy: function(filter) { 
     filtered = this.filter(function(asset) { 
      return asset.get('type') == filter; 
     }); 
     this.trigger('filter'); 
     return new TagsCollection(filtered, {query: this.query}); 
    }, 
    model: AssetModel 
}); 

然后在我看来,我添加了一些东西来呈现我的新集合。

var TagsView = Backbone.View.extend({ 
    initialize: function(query) { 
     this.collection = new TagsCollection([], {query: self.apiQuery}); 
     this.collection.on('sync', function() { 
      self.render(); 
     }); 
     this.collection.on('filter sync', this.filterTemplate, this); 
     this.collection.on('reset', this.render, this); 
    }, 
    render: function() { 
     //renders the template just fine 
    }, 
    filterCollection: function(target) { 
     var filter = $(target).text().toLowerCase().slice(0,-1); 
     if (filter != 'al') { 
      var filtered = this.collection.filterBy(filter); 
     } else { 
      this.render(); 
     } 

    }, 
    filterTemplate: function() { 
     filterResults = new TagsCollection(filtered, {query: self.apiQuery}); 
     console.log(filterResults); 
     $('.asset').remove(); 
     filterResults.each(function(asset,index) { 
      dust.render('dust/academy-card', asset.toJSON(),  function(error,output) { 
       self.$el.append(output); 
      }); 
     }); 
    }, 
}); 

回答

1

下面是这个更好的答案。不要让它变得如此复杂,你可以使用where方法。这是我对上述问题的替代解决方案。

filterby: function(type) { 
     return type === 'all' ? this : new BaseCollection(this.where({type: type}); 
}); 
2

第二次不能正常工作的原因是因为您在拨打reset时删除的模型与您的过滤器不匹配。这是reset函数的正常行为。

而不是渲染与视图的主集合,尝试使用第二个集合只是为了渲染,它代表原始基础集合的过滤数据。因此,您的观点可能看起来像:

var TagsView = Backbone.View.extend({ 

    filter: null, 

    events: { 
     'click .filter-button': 'filter' 
    }, 

    initialize: function (query) { 
     this.baseCollection = new TagsCollection([], {query: self.apiQuery}); 
     this.baseCollection.on('reset sync', this.filterCollection, this); 
     this.collection = new Backbone.Collection; 
     this.collection.on('reset', this.render, this); 
    }, 

    render: function() { 
     var self = this, 
      data = this.collection.toJSON(); 

     // This renders all models in the one template 
     dust.render('some-template', data, function (error, output) { 
      self.$el.append(output); 
     }); 
    }, 

    filter: function (e) { 
     // Grab filter from data attribute or however else you prefer 
     this.filter = $(e.currentTarget).attr('data-filter'); 
     this.filterCollection(); 
    }, 

    filterCollection: function() { 
     var filtered; 

     if (this.filter) { 
      filtered = this.baseCollection.where({'type': this.filter}); 
     } else { 
      filtered = this.baseCollection.models; 
     } 

     this.collection.reset(filtered); 
    } 

}); 

要删除任何过滤器,设定filter-button类按钮,有一个空data-filter属性。 collection然后将重置与所有的baseCollection的模型

+0

感谢您的支持。虽然你的解决方案不是我使用的解决方案,但它促使我做类似的事情。我会在上面更新我的答案。 –

+0

'this.collection.on('reset sync',this.render,this)有什么意义?''?根据你的帖子,原始收藏将不再被重置,而是过滤收藏。是否应该绑定到已过滤的集合?另外,如果原始集合被重置,那么该集合上的委托事件应该触发已被覆盖的'render'以呈现_filtered_集合?我很困惑... – seebiscuit

+0

@Seabiscuit,你说得对'reset'被解雇。这是因为OP在她的代码中存在的原因。为了清晰起见,我只是把它放在那里。重新阅读时会出现一些令人困惑的部分。为了清晰起见,我会编辑。 – Simon