传递骨干集合来查看

时间:2015-06-22 17:07:27

标签: grails backbone.js handlebars.js

我刚刚开始使用骨干/ grails,而且我一直在努力弄清楚如何让一切运转起来。

我正在构建定价配置器,其中用户从无线电组A中选择产品类型,而包含数量/定价/折扣数据的无线电组B将对后端执行ajax调用以获取更新的定价数据。我不想将我的定价算法暴露给前端,所以我想我会使用骨干来处理我的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);

1 个答案:

答案 0 :(得分:2)

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

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

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

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

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

通常,您会将其放在视图类的initialize函数中。这样做是“监听”集合实例,当reset事件发生时,它将调用this.render函数。 (当然,方法this.listenTo可以“监听”其他对象以获取其他事件;请参阅更多详细信息in the Backbone documentation。)

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

但是,默认情况下,当集合中的所有模型都被另一组模型替换时,会发生“重置”事件,并且当您调用集合的fetch方法时,默认情况下不会发生这种情况(而是,该集合将尝试“智能更新”)。要在使用fetch时强制重置集合,请将{reset: true}作为参数传递:

prices.fetch({reset: true});