2012-12-18 9 views
7

Mam następujący szablon ItemView, który jest wypełniony danymi klienta (firstName, lastName) i chcę dodać CollectionView do div .addresses.Marionette.js ItemView - Umieść widok dziecka w regionie

Szablon

<script type="text/html" id="template-customer-details"> 
    <h4><%= firstName %> <%= lastName %></h4> 
    <button class="edit">Edit</button> 
    <h5>Addresses</h5> 
    <div class="addresses">...</div> 
</script> 

Układ

Layout.Details = Backbone.Marionette.ItemView.extend({ 
    template: '#template-customer-details', 

    regions: { 
     addresses: ".addresses" 
    }, 

    serializeData: function() { 
     return this.model.attributes; 
    }, 

    initialize: function() { 

     this.addressList = new App.Models.AddressList(); 

     // Error! 
     this.regions.addresses.show(this.addressList); 

     this.bindTo(this, "render", this.$el.refresh, this.$el); 
     this.model.bind("change", this.render.bind(this)); 
    } 
}); 

otrzymuję błąd "Uncaught TypeError: .addresses obiektu ma metodę 'show'."

Czy muszę czekać na załadowanie widoku?

Odpowiedz

9

Myślę, że niektóre rzeczy są nieco zagmatwane. An ItemView nic nie robi z właściwością regions (możesz myśleć o klasie Application), więc gdy spróbujesz zadzwonić pod numer this.regions.addresses.show, to jest to samo, co wywołanie ".addresses".show.

Myślę, że prawdopodobnie będziesz chciał użyć CompositeView w tym przypadku, ponieważ łączy on w sobie ItemView (który możesz użyć do danych klienta) i CollectionView, którego możesz użyć dla swojej listy adresów. Musisz również zdefiniować osobny adres ItemView (jako CollectionView po prostu tworzy się ItemView dla każdego elementu w kolekcji).

Coś trochę jak ten (które nie zostały przetestowane, więc nie może być całkowicie poprawne):

AddressView = Backbone.Marionette.ItemView.extend({ 
    template: '#addressTemplate' 
}); 

Layout.Details = Backbone.Marionette.CompositeView.extend({ 
    template: '#template-customer-details', 
    itemView: AddressView, 
    itemViewContainer: '.addresses' 
}); 

// Then create your view something like this: 
new Layout.Details({ 
    model: new App.Models.CustomerDetails(), 
    collection: new App.Models.AddressList() 
}); 

Ja też nie sądzę, trzeba specyficznie wiązać się ze zmianami & renderowania zdarzeń jak Twój przykład jako marionetka zwykle to zajmie (to samo z twoją implementacją serializeData, która wygląda jak mgliście taka sama jak domyślna implementacja)

+0

To wygląda dobrze :) Czy mogę też użyć CompositeView, jeśli chcę wyświetlić dwie kolekcje poniżej danych klienta (jedna dla adresów i jedna dla kontaktów), czy też powinienem użyć Układu? – Dennis

+1

@Dennis - użyj w Layout dla tego –

+0

Dla bieżącej wersji, która jest 3.0, itemView i itemViewContainer w CompsoiteView, powinny być childView i childViewContainer. zmień nazwę "przedmiotu" na "dziecko". http://marionettejs.com/docs/v2.4.7/marionette.compositeview.html#compositeviews-childview –