2013-02-12 78 views
6

我正在使用backbone和marionette.js构建应用程序。我打算使用集合视图呈现一些项目,然后允许对它们进行过滤,排序和分组。使用Marionette将集合视图中的项目分组

我想知道是否有任何好的设计思想实际追加在分组的方式的HTML。我有一些想法,但我想知道如果有人可能会有更好的设计投入。

我的第一个想法是更改集合视图中的appendHtml方法,如果启用了分组,则可以使用appendHtml函数查找或创建子组的bin并将子视图放入其中。

appendHtml: function(collectionView, itemView, index){ 
    var $container = this.getItemViewContainer(collectionView); 

    // get group from model 
    var groupName = itemView.model.get("group"); 

    // try to find group in child container 
    var groupContainer = $container.find("." + groupName); 

    if(groupContainer.length === 0){ 
    // create group container 
    var groupContainer = $('<div class="' + groupName + '">') 
    $container.append(groupContainer); 
    } 

    // Append the childview to the group 
    groupContainer.append(itemView); 
} 

我的第二个想法是掰开收集到第一,然后也许渲染多个视图组...这一个看起来可能是更多的工作,但也可能会好一点,只要代码结构而言。

任何建议或思想引出的评论将是伟大的!

感谢

+0

我喜欢你的第一种方法更好,它可能是更容易了。演示文稿应该在视图中,分割一个集合以显示不同的内容似乎很奇怪。在某些时候,您可能想要一个按钮来切换列表视图是否被分组,然后多个集合可能会阻碍。 – 2013-02-13 00:09:54

+0

是的,那是我和我一起去的......我确实需要更小心一些,因为我想为每个组添加标题......这意味着我需要确保我跟踪这些。这是不幸的,因为木偶在跟踪添加/删除项目方面做得非常出色,无需太多额外的... – MattyP 2013-02-13 03:41:58

+0

我想知道,如果您添加一个“比较器”到您的收藏集以便按组排序,这是否会有所帮助。然后,当有任何添加/删除/重置更改,在视图中,你可以做一个后处理步骤,在木偶做插入/删除,插入标题...我想有1000种方法可以做任何事情。 – 2013-02-13 03:48:47

回答

7

你要找的也许不完全是,但这里有一个有点相关的问题:

Backbone.Marionette, collection items in a grid (no table)

我解决这个问题 - 一个牵强的集合,可以被渲染成列表或网格(“按行分组的项目”)是在“包装器”CompositeView中使用_.groupBy(),并将修改后的数据沿着链传递到另一个CompositeView(行),然后传递到ItemView。

Views.Grid = Backbone.Marionette.CompositeView.extend({ 
    template: "#grid-template", 
    itemView: Views.GridRow, 
    itemViewContainer: "section", 
    initialize: function() { 
     var grid = this.collection.groupBy(function(list, iterator) { 
      return Math.floor(iterator/4); // 4 == number of columns 
     }); 
     this.collection = new Backbone.Collection(_.toArray(grid)); 
    } 
}); 

这里有一个演示:

http://jsfiddle.net/bryanbuchs/c72Vg/

+0

这就是我想到的第二个想法的想法......我想要做的一件事情仍然是处理过滤......而事情是分组的......所以我想我必须连线所有的子收藏品,以听取父母的添加/删除/重置......我真的开始喜欢这个想法更多,因为我想起它... – MattyP 2013-02-13 17:03:57

3

我做您的两个建议的东西,他们都很好地工作。它主要归结为你喜欢哪一个,也许哪一个更适合你的情况。

如果您的数据已经在分组层次结构中,请使用许多层次模型/集合插件之一或您自己的层次结构代码,然后再渲染一个组列表的想法,每个组渲染一个项目列表可能更容易。

如果您的数据是平坦的,但包含您将分组的字段,那么appendHtml更改可能会更容易一些。

心连心

1

这是除了Derick'sbryanbuchs'答案。我的方法使用主集合视图和另一个集合视图作为其子视图。

集合视图有一个'addChild'方法,只要将模型添加到视图的集合中,该方法就会被调用。 'addChild'方法负责呈现子视图并将其添加到给定索引处的集合视图的HTML中。你可以在github上看到源代码here。我会在这里贴了简化:

addChild: function(child, ChildView, index) { 
    var childViewOptions = this.getOption('childViewOptions'); 
    if (_.isFunction(childViewOptions)) { 
     childViewOptions = childViewOptions.call(this, child, index); 
    } 

    var view = this.buildChildView(child, ChildView, childViewOptions); 

    // increment indices of views after this one 
    this._updateIndices(view, true, index); 
    this._addChildView(view, index); 
    return view; 
} 

正如你可以看到“的addChild”方法调用“buildChildView”的方法。这种方法实际上构建了视图。

// Build a `childView` for a model in the collection. 
buildChildView: function(child, ChildViewClass, childViewOptions) { 
var options = _.extend({model: child}, childViewOptions); 
return new ChildViewClass(options); 
} 

因此,对于您的用例,您可以重写'addChild'方法,并在分组条件匹配时调用原始方法。然后在重写的“buildChildView”方法中,您可以将该组(这是您的集合的一个子集)传递给它的childView,这是另一个Marionette.CollectionView。

例子:

MyCollectionView.prototype.addChild = function(child, ChildView, index) { 
    if(mycriteria){ 
     return ProductGroup.__super__.addChild.apply(this, arguments); 
    } 
}; 

MyCollectionView.prototype.buildChildView = function(child, ChildViewClass, 
childViewOptions) { 

    options = _.extend({ 
     collection: "Pass your group collection which is a subset of your main collection"}, 
     childViewOptions 
    ); 

    return new ChildViewClass(options); 
    }; 
相关问题