Marionette.js ItemView - поместить дочерний вид в регион

У меня есть следующий шаблон ItemView, который заполнен данными клиента (firstName, lastName), и я хочу добавить CollectionView в div .addresses.

Шаблон

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

Макет

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

Я получаю сообщение об ошибке «Uncaught TypeError: Object .addresses не имеет метода show».

Должен ли я ждать, пока представление загрузится?


person Dennis    schedule 18.12.2012    source источник


Ответы (1)


Я думаю, вы немного запутались. ItemView ничего не делает со свойством regions (вы можете иметь в виду класс Application), поэтому когда вы пытаетесь вызвать this.regions.addresses.show, это то же самое, что и вызов ".addresses".show.

Я думаю, вы, вероятно, захотите использовать CompositeView в этом случае, так как он сочетает в себе ItemView (который вы можете использовать для своих данных о клиентах) и CollectionView, который вы можете использовать для своего списка адресов. Вам также потребуется определить отдельный ItemView для адреса (поскольку CollectionView просто создает ItemView для каждого элемента в коллекции).

Что-то вроде этого (которое я не проверял, поэтому может быть не совсем правильно):

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

Я также не думаю, что вам нужно специально привязывать события изменения и рендеринга, как в вашем примере, поскольку марионетка обычно позаботится об этом (то же самое с вашей реализацией serializeData, которая выглядит так же, как реализация по умолчанию)

person obmarg    schedule 18.12.2012
comment
Это выглядит хорошо :) Могу ли я также использовать CompositeView, если я хочу отображать две коллекции под данными клиента (одну для адресов и одну для контактов), или тогда мне следует использовать макет? - person Dennis; 19.12.2012
comment
@Dennis - используйте для этого в Layout - person Derick Bailey; 19.12.2012
comment
Для текущей версии 3.0 itemView и itemViewContainer в CompsoiteView должны быть childView и childViewContainer. переименуйте «элемент» в «дочерний». marionettejs.com/docs/v2.4.7/ - person Expert wanna be; 25.08.2016