Подвид backbone.js не отображается при первоначальном рендеринге

У меня есть мнение:

App.Views.Rebill = App.Views.baseView.extend({
    view: 'requests._rebill_line',
    tag: 'div',
    className: 'row row-spaced',

    render: function() {
        var self = this;
        App.get_view(self.view).done(function(data){
            var view = Mustache.render(data, {
                text: self.model.get('text'),
                cost: self.model.get('cost')
            });

            self.$el.append(view);

            var $selectVat = self.$el.find('select[name="vat"]');
            var vatPicker = new App.Views.VatPicker({
                model: self.model,
                el: $selectVat
            });
            vatPicker.render();
        });
        return self;
    }
});

это представление создается в родительском:

addRebillLine: function(rebillModel){
    var self = this;
    var rebillView = new App.Views.Rebill({
        model: rebillModel
    });
    self.$el.after(rebillView.render().$el);
},

Я связал это с кнопкой, которая создает пустую модель и вызывает функцию addRebillLine. Это нормально работает, новое представление Rebill появляется в DOM, когда я нажимаю кнопку.

Однако при рендеринге родительского представления я просматриваю массив json, создаю модель с каждой строкой и вызываю функцию addRebillLine с этой моделью. Это выполняется, но представления Rebill не добавляются в DOM.

Далее, родительское представление само по себе является дочерним представлением и прикреплено к своему родителю следующим образом:

this.$el.find('[data-role="repair-items"]').append(itemView.render().$el);

Родительские и прародительские представления обрабатываются синхронно, а дочернее представление асинхронно (App.get_view () в основном является вызовом $ .ajax, следовательно, .done ())

Странно то, что я делаю то же самое с представлением App.Views.VatPicker в нескольких других местах, и это прекрасно работает. Единственная разница в том, что я передаю элемент для присоединения к представлению VatPicker. Но если я передам родительский элемент $el и запустил this.$parent.after(self.$el) в моем done() обратном вызове, это тоже не сработает.


person Tom Macdonald    schedule 10.04.2014    source источник
comment
Я решил проблему, добавив обратный вызов, который вызывается функцией done () и добавляет дочерний $ el к родительскому $ el. Но я до сих пор не понимаю, почему приведенный выше код не отображается.   -  person Tom Macdonald    schedule 10.04.2014


Ответы (1)


Когда вы звоните на эту линию:

this.$el.find('[data-role="repair-items"]').append(itemView.render().$el);

он предполагает, что ваш код рендеринга синхронный (как и должно быть), но ваш рендеринг - нет. При возврате рендеринга $ el еще не установлен, это проблема вашего дизайна.

Вы должны решить эту проблему дизайна, сделав свои шаблоны доступными, когда они понадобятся представлению. Не изобретайте здесь колесо, взгляните на пример магистрали TodoMVC.

Если вы хотите, чтобы ваши шаблоны загружались aysnc, используйте requirejs.

person ekeren    schedule 10.04.2014