【问题标题】:Marionette.js CollectionView, only render specific modelsMarionette.js CollectionView,只渲染特定模型
【发布时间】:2013-09-07 09:26:36
【问题描述】:

我正在重构我的 Backbone.js 应用程序以使用 Marionette.js,并且我正试图围绕 CollectionView.

假设我有几个ItemViews 和模型Cow

// Declare my models.
var Cow = Backbone.Model.extend({});
var Cows = Backbone.Collection.extend({
  model: Cow
});

// Make my views
var GrassPatch = Marionette.ItemView.extend({
  tagName:  'div',
  template: "<section class='grass'>{{name}}</section>",
})

var Pasture = Marionette.CollectionView.extend({});

// Instantiate the CollectionView,
var blissLand = new Pasture({
  itemView: GrassPatch;
});

// Now, add models to the collection.
Cows.add({
  name: 'Bessie',
  hasSpots: true
});

Cows.add({
  name: 'Frank',
  hasSpots: false
});

现在这是诀窍。我只想要牧场上有斑点的奶牛。如何在定义我的 CollectionView(牧场)时告诉它只关注那些 hasSpots === true 的模型?

理想情况下,我希望在所有事件中都有 CollectionView 过滤器,但至少,我如何仅根据其模型属性呈现一些 ItemView?

更新

我使用了 David Sulc 的示例,这是一个简单的解决方案。这是一个示例实现:

  this.collection = Backbone.filterCollection(this.collection, function(criterion){
    var len = String(criterion).length;
    var a = criterion.toLowerCase();
    return function(model){
      var b = String(model.get('name')).substr(0, len).toLowerCase();
      if (a === b) {
        return model;
      }
    };
  });

  this.collection.add({ name: 'foo' });
  this.collection.add({ name: 'foosball' });
  this.collection.add({ name: 'foo bar' });
  this.collection.add({ name: 'goats' });
  this.collection.add({ name: 'cows' });

  this.collection.filter('foo');

  // -> returns the first three models

【问题讨论】:

标签: javascript jquery model-view-controller backbone.js marionette


【解决方案1】:

@Will M 建议过滤集合是合适的方法。

【讨论】:

    【解决方案2】:

    正如其他人所建议的,实现此目的的最佳方法是过滤集合以仅包含您要显示的模型,并将经过过滤的集合传递给 CollectionView 进行渲染。

    您可以在此处查看一个工作示例:http://davidsulc.github.io/marionette-gentle-introduction/#contacts 使用右上角的输入字段过滤联系人以仅显示包含该文本的模型(例如“li”)。

    这是通过使用处理过滤的特殊集合类型来实现的:https://github.com/davidsulc/marionette-gentle-introduction/blob/master/assets/js/entities/common.js

    它在这里被实例化:https://github.com/davidsulc/marionette-gentle-introduction/blob/master/assets/js/apps/contacts/list/list_controller.js#L13

    此代码来自我的book on Marionette

    【讨论】:

    【解决方案3】:

    有时,由于某些自定义逻辑,您无法过滤您的集合,并且您希望这些模型位于集合中,但您不希望它们被呈现。要实现它,您可以:

    var Pasture = Marionette.CollectionView.extend({
         addChild: function(child, ChildView, index) {
                   if(child.get('hasSpots')) {
                        return Marionette.CollectionView.prototype.addChild.call(this, child, ChildView, index);
                   }
         }});
    

    虽然我同意过滤集合是一种更好的方法。

    【讨论】:

      【解决方案4】:

      Marionette 在 v2.4.1 中为您处理。

      参见CollectionView.filter 方法。

      以下来自文档:

        var cv = new Marionette.CollectionView({
          childView: SomeChildView,
          emptyView: SomeEmptyView,
          collection: new Backbone.Collection([
            { value: 1 },
            { value: 2 },
            { value: 3 },
            { value: 4 }
          ]),
      
          // Only show views with even values
          filter: function (child, index, collection) {
            return child.get('value') % 2 === 0;
          }
        });
      
        // renders the views with values '2' and '4'
        cv.render();
      
        // change the filter
        cv.filter = function (child, index, collection) {
          return child.get('value') % 2 !== 0;
        };
      
        // renders the views with values '1' and '3'
        cv.render();
      
        // remove the filter
        // note that using `delete cv.filter` will cause the prototype's filter to be used
        // which may be undesirable
        cv.filter = null;
      
        // renders all views
        cv.render();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-18
        相关资源
        最近更新 更多