我刚刚开始使用骨干/ 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);
答案 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});