传递 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});
我刚开始使用 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});