2012-11-26 28 views
11

Dostaję się do większych struktur danych z kręgosłupem i przychodzi czas, w którym dane będą dobrze reprezentowane przez CompositeViews; to jest, CollectionViews z dodatkiem "dodał puch" wokół nich, takich jak nagłówki, przyciski, i tak dalej.Jak obsłużyć zagnieżdżony CompositeView za pomocą Backbone.Marionette?

Mam jednak wiele problemów ze scalaniem widoków CompositeViews wewnątrz siebie. Używanie standardowej właściwości itemView w CompositeView do renderowania innego CompositeView w ogóle nie działa.

Załóżmy mam rodzic ItemView instancję jako taki (po Derick Bailey's example; zakładamy, top poziom jest gdzie początkowy fetch() sprawie zbierania byłoby nazwać):

var User = Backbone.Model.extend({}); 

var UserCollection = Backbone.Collection.extend({ 
    model: User 
}); 

var userList = new UserCollection(userData); 

var schedulerCompositeView = new SchedulerCompositeView({ 
    collection: userList 
}); 

schedulerCompositeView.render(); 

this.ui.schedulerWidget.html(schedulerCompositeView.el); 

I SchedulerCompositeView wygląda jak takie:

return Backbone.Marionette.CompositeView.extend({ 
    template: Handlebars.compile(schedulerCompositeViewTemplate), 
    itemView: SchedulerDetailCompositeView, 
    appendHtml: function (collectionView, itemView) { 
     collectionView.$("#schedulerGroups").append(itemView.el); 
    } 
}); 

I wreszcie, SchedulerDetailCompositeView:

return Backbone.Marionette.CompositeView.extend({ 
    template: Handlebars.compile(schedulerDetailCompositeViewTemplate), 
    itemView: SchedulerDetailItemView, 
    appendHtml: function (collectionView, itemView) { 
     collectionView.$("#schedulerDetailStops").append(itemView.el); 
    } 
}); 

SchedulerDetailCompositeView nigdy nie zostanie utworzony; w rzeczywistości jego metoda appendHtml() nigdy nie wydaje się strzelać w ogóle.

Najwyraźniej brakuje tu innych informacji; oczywiście celem jest przekazanie kolekcji/modelu do SchedulerDetailCompositeView, ale nie jestem do końca pewien, jaka jest właściwa technika, z powodu zagnieżdżonych widoków CompositeView.

Dla porównania, oto przybliżona makieta struktury, którą próbuję osiągnąć; jeśli nie może być lepszy sposób na osiągnięcie tego celu niż zagnieżdżonych CompositeViews, jestem na pewno wszystkie uszy:

http://jsfiddle.net/KAWB8/

+2

Wewnętrzna funkcja inicjalizacji SchedulerDetailCompositeView, którą należy jawnie przypisać do this.collection, tj. Przekazać złożony widok o zbiorze, z którym ma do czynienia. Podobnie jak w tym [widok drzewa] (http://jsfiddle.net/derickbailey/AdWjU/) skrzypce – deven98602

+0

To nie wydaje się być wystarczającą informacją.Nawet po przypisaniu kolekcji za pomocą metody initialize, appendHtml w SchedulerDetailCompositeView nigdy nie uruchamia się. Inicjalizacja ma, ale appendHtml nie. –

Odpowiedz

16

Eureka! Zostałem ustawiony na poprawnej ścieżce przez deven98602.

Kluczem do zapamiętania jest to, że jeśli zagnieżdżasz wiele widoków CompositeView (lub CollectionViews), każdy poziom kaskadowy będzie reprezentował jedną jednostkę zestawu od rodzica; oznacza to, że mój poprzedni model reprezentuje pojedynczy model z kolekcji w SchedulerCompositeView. Dlatego, jeśli konstruuję zagnieżdżone CompositeViews (prawdopodobnie oparte na głęboko zagnieżdżonych danych), muszę ponownie zdefiniować kolekcję na tych kaskadowych elementach potomnych, ponieważ mają one tylko jeden model skojarzony z nimi, a nie prawidłową kolekcję do renderowania.

Powiedział, że zaktualizowane SchedulerDetailCompositeView wygląda w następujący sposób:

return Backbone.Marionette.CompositeView.extend({ 
    template: Handlebars.compile(schedulerDetailCompositeViewTemplate), 
    itemView: SchedulerDetailItemView, 
    initialize: function() { 
     var Load = Backbone.Model.extend(); 

     var LoadCollection = Backbone.Collection.extend({ 
      model: Load 
     }); 

     // this array of loads, nested within my JSON data, represents 
     // a new collection to be rendered as models using SchedulerDetailItemView 
     var loadList = new LoadCollection(this.model.get("loads")); 

     this.collection = loadList; 
    }, 
    appendHtml: function (collectionView, itemView) { 
     collectionView.$("#schedulerDetailStops").append(itemView.el); 
    } 
}); 

Gdy kolekcja jest ustawiony, appendHtml() pożarów zgodnie z oczekiwaniami i czyni każdego nowego modelu w tym nowo ustawionym kolekcji.

+2

Miałem nadzieję, że Marionette (/ Backbone) był na tyle sprytny, aby poradzić sobie z tym dla mnie, ale tak nie jest. +1 dla pytania i odpowiedzi – Bojangles

+1

Nie zdefiniowałbym jednak klasy lokalnej za każdym razem. To jest marnotrawstwo. – demonkoryu

Powiązane problemy