7

バックボーンとmarionette.jsを使用してアプリケーションを構築しています。コレクションビューを使用していくつかのアイテムを表示し、それらをフィルタリング、並べ替え、グループ化できるようにすることを計画しています。

グループ化された方法で実際にhtmlを追加するための良いデザインのアイデアがあるかどうか疑問に思いました。いくつかのアイデアがありますが、どちらがより良いデザインになるかについて誰かが意見を述べているのではないかと思っていました。

私の最初のアイデアは、コレクションビューのappendHtmlメソッドを変更することです。グループ化が有効になっている場合は、appendHtml関数で子グループのビンを検索または作成し、その中に子ビューを配置できます。

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);
}

私の2番目のアイデアは、最初にコレクションをグループに分割してから、複数のビューをレンダリングすることです...これは、より手間がかかるように見えますが、コード構造に関する限り、少し優れている可能性もあります。

コメントを引き出す提案や考えは素晴らしいでしょう!

ありがとう

4

3 に答える 3

7

あなたが探しているものとは正確には異なるかもしれませんが、これはやや関連する質問です:

Backbone.Marionette、グリッド内のコレクション アイテム (テーブルなし)

その問題に対する私の解決策-リストまたはグリッド(「行にグループ化されたアイテム」)としてレンダリングできるフェッチされたコレクションの1つは、「ラッパー」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/

于 2013-02-13T15:59:34.513 に答える
4

私はあなたが提案したことの両方を実行しましたが、どちらもうまく機能します。それは主に、どちらを好むか、そしておそらくどちらがシナリオに適しているかにかかっています。

多くの階層モデル/コレクション プラグインの 1 つまたは独自の階層コードを使用して、グループ化された階層に既にデータがある場合は、グループのリストをレンダリングし、各グループがアイテムのリストをレンダリングするという考えの方がおそらく簡単です。

フラットなデータがあるが、グループ化するフィールドが含まれている場合、appendHtml の変更はおそらく簡単になります。

h番目

于 2013-02-13T14:24:09.690 に答える
1

これは、Derickbryanbuchs の回答に追加されたものです。私のメソッドは、メイン コレクション ビューと別のコレクション ビューをその childView として使用します。

コレクション ビューには「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」メソッドで、グループ (コレクションのサブセット) を別の Marionette.CollectionView であるその childView に渡すことができます。

例:

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);
  };
于 2014-09-05T13:54:50.277 に答える