1

我有我的骨干路由器:

var AppRouter = Backbone.Router.extend({

    routes:{
        "" : "productos",
    },

    initialize: function(){
        this.productoItem = new Producto();
        //Crear la vista del detalle de un producto

        this.productoItems = new Productos();
        this.productoItems.fetch();

        this.productosView = new ProductsView({collection: this.productoItems});
    },

    productos: function(){
        $('#app').html(this.productosView.render().el);
      //this line seems not to working but putting in a console does the work
    }

});

/*********************************/
var app = new AppRouter();

$(function(){
    Backbone.history.start();
});

观点如下:

var ProductsView = Backbone.View.extend({

    render: function(){
        this.$el.html(Handlebars.templates.products(this.collection));
        return this;
    }
});

最后是我的车把模板:

<h1>Y LOS MODELOS SON</h1>
<ul>
{{#each models}}
<li>
{{attributes.familia}}
</li>
{{/each}}
</ul>

所以当我运行这个应用程序时,它只会呈现 Y LOS MODELOS SON,这意味着 $('#app').html(this.productosView.render().el);工作但不完全只有html标签......但是当我这样做时:

$('#app').html(app.productosView.render().el)

在控制台中它完美地工作......有人可以解释一下我错过了什么吗?谢谢...

4

1 回答 1

0

Collection#fetch是一个 AJAX 调用,所以AppRouter#productos在服务器发回任何东西之前被调用。结果是集合在ProductsView#render被调用时为空,并且{{#each models}}在您的模板中没有可迭代的内容。

Collection#fetch用于Collection#set将获取的模型合并到集合中。这将触发集合上的"add""remove""change"事件。您可以从集合中侦听这些事件并重新渲染:

initialize: function() {
    this.listenTo(this.collection, 'add remove change', this.render);
}

但这将非常浪费,因为您将为每个新添加的模型重新渲染视图。另一种方法是使用 fetch {reset:true}

当模型数据从服务器返回时,它使用set来(智能地)合并获取的模型,除非您通过{reset: true},在这种情况下,集合将(有效地)重置

并将reset触发单个"reset"事件。所以在你的路由器中,你可以说:

this.productoItems = new Productos();
this.productoItems.fetch({ reset: true });

然后在你看来:

initialize: function() {
    this.listenTo(this.collection, 'reset', this.render);
}

在您的情况下,使用{reset: true}似乎是最容易使用的东西。

于 2013-10-21T02:49:03.513 回答