2013-02-12 11 views
6

Ich baue eine Anwendung mit Backbone und marionette.js. Ich beabsichtige, eine Sammlungsansicht zu verwenden, um einige Elemente darzustellen und dann zu erlauben, dass sie gefiltert, sortiert und gruppiert werden.Verwenden von Marionette zum Gruppieren von Objekten in einer Sammlungsansicht

Ich frage mich, ob es gute Design-Ideen für die tatsächliche Anhängen der HTML in einer gruppierten Mode gibt. Ich habe ein paar Ideen, aber ich habe mich gefragt, ob jemand etwas einbringen könnte, um besser zu entwerfen.

Meine erste Idee ist es, die AppendHtml-Methode für die Sammlungsansicht zu ändern, und wenn die Gruppierung aktiviert ist, kann ich die AppendHtml-Funktion entweder suchen oder erstellen die Bin der untergeordneten Gruppe und legen Sie die untergeordnete Ansicht darin.

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

Meine zweite Idee ist es, die Sammlung in Gruppen auseinander zu brechen und dann vielleicht mehrere Ansichten machen ... Dies scheint wie könnte es mehr Arbeit, aber vielleicht auch etwas besser sein, so weit wie der Code Struktur betrifft.

Alle Vorschläge oder Gedanken, die Kommentare auslösen, wären großartig!

Dank

+0

Ich mag Ihren ersten Ansatz besser, und es ist wahrscheinlich zu erleichtern. Präsentationsmaterial sollte in der Ansicht sein, und es erscheint seltsam, eine Sammlung aufzuteilen, nur um sie anders darzustellen. Irgendwann möchten Sie vielleicht eine Schaltfläche, um zu ändern, ob die Listenansicht gruppiert ist, und dann könnten mehrere Sammlungen in die Quere kommen. –

+0

Ja, das ist die, mit der ich ging ... Ich muss aber auf diese Weise ein wenig vorsichtiger sein ... weil ich jeder Gruppe Überschriften hinzufügen wollte ... was dann bedeutet, dass ich sicherstellen muss, dass ich Behalten Sie diese auch im Auge. Was unglücklich ist, weil Marionette eine großartige Arbeit leistet, um die Hinzufügung/Entfernung von Gegenständen zu überwachen. – MattyP

+0

Ich frage mich, ob es hilfreich wäre, wenn Sie Ihrer Sammlung einen 'Komparator' hinzufügen, der nach Gruppe sortiert ist. Dann, wenn es eine Änderung hinzufügen/entfernen/zurücksetzen, in der Ansicht können Sie eine Art von Post-Processing-Schritt, nachdem Marionette das Einfügen/Entfernen, um die Header einfügen ... Ich denke, es gibt 1000 Möglichkeiten, etwas zu tun. –

Antwort

7

Vielleicht nicht genau das, was Sie suchen, aber hier ist eine etwas ähnliche Frage:

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

Meine Lösung für dieses Problem - eine Sammlung geholt, die als gerendert werden konnte Eine Liste oder ein Raster ("Elemente in Zeilen gruppiert") sollte _.groupBy() in einem "Wrapper" CompositeView verwenden und modifizierte Daten in der Kette an eine andere CompositeView (Zeile) und dann an eine ItemView übergeben.

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

Hier ist eine Demo:

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

+0

Das ist die Idee, die ich mir für meine zweite Idee ausgedacht habe ... die eine Sache, die ich gerne machen würde, ist immer noch Filterung ... und so, während die Dinge gruppiert sind ... Also ich stelle mir vor ich müsste verdrahten Sie alle Untersammlungen, um für add/remove/reset der Eltern zu hören ... Ich fange tatsächlich an, diese Idee mehr zu mögen, während ich darüber nachdenke ... – MattyP

3

Ich habe beide der Dinge getan, um Ihren was darauf hindeutet, und sie beide gut funktionieren. Es kommt weitgehend darauf an, welche Sie bevorzugen und welche besser zu Ihrem Szenario passt.

Wenn Sie Daten haben, die sich bereits in einer gruppierten Hierarchie befinden, indem Sie eines der vielen hierarchischen Modell-/Sammlungs-Plugins oder Ihren eigenen Hierarchiecode verwenden, dann sollten Sie eine Liste von Gruppen darstellen, wobei jede Gruppe eine Liste von Elementen rendert ist wahrscheinlich einfacher.

Wenn Sie Daten haben, die flach sind, aber ein Feld enthalten, nach dem Sie gruppieren, werden die Änderungen von appendHtml wahrscheinlich einfacher.

hth

1

Dies ist zusätzlich zu Derick's und bryanbuchs' Antworten. Meine Methode verwendet eine Hauptsammlungsansicht und eine andere Auflistungsansicht als ihre untergeordnete Ansicht.

Sammlungsansichten verfügen über eine addChild-Methode, die aufgerufen wird, wenn ein Modell der Sammlung der Ansicht hinzugefügt wird. Die Methode 'addChild' ist dafür verantwortlich, die Ansicht des untergeordneten Elements zu rendern und sie dem HTML-Code für die Sammlungsansicht eines bestimmten Indexes hinzuzufügen. Sie können den Quellcode auf github here sehen. Ich werde hier einfügen zur Vereinfachung:

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

Wie Sie die ‚addChild‘ Methode sehen ruft die ‚buildChildView‘ -Methode. Diese Methode erstellt die Ansicht tatsächlich.

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

Also für Ihren Anwendungsfall können Sie die ‚addChild‘ Methode überschreiben und einen Aufruf an die ursprünglichen Methode, wenn Ihre Gruppierungskriterien abgestimmt ist. Und dann können Sie in der überschriebenen "buildChildView" -Methode die Gruppe (die eine Untermenge Ihrer Sammlung ist) an ihre untergeordnete Ansicht übergeben, die eine andere Marionette.CollectionView ist.

Beispiel:

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