我有两个 API 端点:
/products
(带有与其关联的Product
模型),以及
/stockitems
(对应于我的 Backbone.js 应用程序中的 StockItems
集合)。
要渲染 StockItems
Collection View ,我首先获取集合,然后为其中的每个模型获取 Product
(例如 /products/1499
)以获得一些附加信息。
我的第一次尝试如下。
var stock = new App.Collections.StockItems();
stock.fetch().success(function(){
for (var i in stock.models) {
var product = new App.Models.Product({id: stock.models[i].get('product_id')});
product.fetch().success(function(){
stock.models[i].set('img', product.get('image_url_1'));
});
}
});
但是,这样只有最后一个 stock.model
才会使用附加属性进行更新。我有预感,如果我等待所有这些都获取然后更新,它就会起作用。这是我的第二次尝试。
var stock = new App.Collections.StockItems(),
product = [],
count;
stock.fetch().success(function(){
count = stock.models.length;
for (var i in stock.models) {
product[i] = new App.Models.Product({id: stock.models[i].get('product_id')});
product[i].fetch().success(function(){
count--;
if (count === 0) {
for (i in stock.models) {
stock.models[i].set('img', product[i].get('image_url_1'));
}
}
});
}
});
它现在可以工作了,但是我不确定我是否理解为什么我需要那个计数器和额外的循环。我也觉得应该有更好的方法来做到这一点。也许在 Backbone View 中包含获取指令?
以下是我的模型/集合/ View 定义。
window.App = {
Models: {},
Views: {},
Collections: {}
};
App.Models.Product = Backbone.Model.extend({
urlRoot: 'http://mysite/api/products'
});
App.Models.StockItem = Backbone.Model.extend({});
App.Collections.StockItems = Backbone.Collection.extend({
model: App.Models.StockItem,
url: 'http://mysite/api/stock'
});
App.Views.StockItem = Backbone.View.extend({
tagName: 'li',
template: _.template( $('#stockItemTemplate').html() ),
render: function() {
this.$el.html( this.template(this.model.toJSON()) );
return this;
}
});
App.Views.StockItems = Backbone.View.extend({
tagName: 'ul',
initialize: function() {
this.$el.empty();
},
render: function() {
this.$el.empty();
this.collection.each(this.addOne, this);
return this;
},
addOne: function(stock_item) {
var stock_item = new App.Views.StockItem({ model: stock_item });
this.$el.append( stock_item.render().el );
}
});
最佳答案
现在我明白您希望在显示库存商品时显示产品图像,因此您要求库存商品中的每个模型循环获取图像。
这效率不高,伙计。想象一下您将向服务器发送多少请求!
不要多次获取。一次性完成。嵌套的获取确实没有必要。
简单的解决方案
看起来您不需要同时查看产品。因此,最简单的解决方案只是从服务器传递 JSON 集合,并在每个模型中包含产品图像 url。完成。
高级解决方案
我认为简单的解决方案就足够了。从服务器在模型中添加额外的图像 url 字段只需要很少的资源。因此,即使您有时间不需要图像,您也可以将图像数据保存在那里,不会造成任何损害。
但是,如果您仍然想要更多控制,您可以设置一个参数来要求服务器添加或不添加图像
// StockItemsCollection
url: function(){
return 'http://example.com/stock' + this.params;
};
params: ''
当您需要图片时,可以在获取图片之前在param
中添加&with_image=true
,服务器可以根据此参数响应是否传递图片。相当灵活。
关于javascript - Backbone.js 中的嵌套获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20721440/