传递 backbone 个集合以供查看

passing backbone collection to view

我刚开始使用 backbone / grails,我一直在努力弄清楚如何让一切正常工作。

我正在构建一个定价配置器,用户可以在其中选择包含数量/定价/折扣数据的无线电组 A 和无线电组 B 的产品类型,然后 ajax 调用后端以更新定价数据。我不想将我的定价算法暴露给前端,所以我想我会使用 backbone 来处理我的 ajax 请求/模板。

我不想完全依赖 js 来创建我的 UI,因此在初始页面加载时,我将使用 grails 构建 gsp 视图。我注意到的唯一问题是我的 gsp 视图在初始页面加载时被我的车把模板所取代。我想这很好,除了它执行两个不是最佳的相同查询。

无论如何,我的代码似乎不起作用。

<script id="priceTemplate" type="text/x-handlebars-template">
    <tr>
        <td><input type="radio" value="" name="quantity">{{quantity}}</td>
         <td class="price"><span>{{price}}</span></td>
        <td class="discount"><span>{{discount}}</span></td>
    </tr>
</script>

<asset:javascript src="bb_product/config.js"/>

<script>   
    var prices = new models.PriceList([],{productId:${productInstance.id}});
    var priceView = new PriceView({collection: prices});
    prices.fetch();     
</script>

型号

var models = {};

models.PriceModel = Backbone.Model.extend({   
    //Is the model automatically populated from the collections json response?
})

models.PriceList = Backbone.Collection.extend({
    initialize: function(models, options) {     
        this.productId = options.productId;
    },
    model: models.PriceModel,
    url: function() {
           return '../product/pricing/' + this.productId + '.json'
        }  
});

查看

var PriceView = Backbone.View.extend({
    el: '#product-quantities',

    template: Handlebars.compile($("#priceTemplate").html()),

    initialize: function(){
        this.render();
    },

   render: function() {
       console.log('collection ' + this.collection.toJSON()) //comes back empty
       this.$el.html( this.template(this.collection.toJSON()));
   }

});

json 从 url

返回
[{"id":1,"quantity":10,"price":"10","discount":"10"},{"id":2,"quantity":50,"price":"20","discount"
:"10"}]

为了初步启动并运行,我缺少什么来显示 json 对象中的所有项目?

我也看到过这段代码,但不确定它的作用this.listenTo(this.collection, 'reset', this.render);

您看不到任何项目的原因是在呈现视图之前,这些项目实际上并不在集合中。看这两行代码:

var priceView = new PriceView({collection: prices});
prices.fetch();

第一行呈现视图(因为您是从 initialize 中调用 render)。但是,那时 prices 集合是空的。然后,第二行从服务器获取数据并将其加载到集合中;但到那时,视图已经呈现。

您发布的最后一行代码是解决此问题的关键:

this.listenTo(this.collection, 'reset', this.render);

通常,您会将其放在视图 class 中的 initialize 函数中。它所做的是"listen"到集合实例,当reset事件发生时,它会调用this.render函数。 (当然,方法this.listenTo可以"listen"到其他对象进行其他事件;详见in the Backbone documentation)。

如果将该行添加到视图的 initialize 函数中,只要集合上发生 "reset" 事件,视图就会重新呈现。

但是,默认情况下,"reset" 事件会在集合中的所有模型都被另一组模型替换时发生,而当您调用集合的 fetch 方法(相反,集合将尝试 "smart-update")。要在使用 fetch 时强制重置集合,请将 {reset: true} 作为参数传递:

prices.fetch({reset: true});