backbone.js子视图未在初始渲染中显示

时间:2014-04-10 06:24:32

标签: javascript backbone.js backbone-views

我有一个观点:

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(),那么它也无法正常工作。

1 个答案:

答案 0 :(得分:0)

当你拨打这一行时:

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

它假定您的渲染代码是同步的(应该是),但是渲染代码不是。 当渲染返回时,$ el尚未设置,这是您设计中的一个问题。

您应该通过在视图需要时使模板可用来解决此设计问题。不要在这里发明轮子,看看TodoMVC主干示例。

如果您希望加载模板aysnc,请使用requirejs。