javascript - Backbone.js 中的嵌套获取

标签 javascript backbone.js fetch

我有两个 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/

相关文章:

javascript - 显示带有自定义身份验证 header 的 IFrame IPython

javascript - 在for循环中对数字进行排序

javascript - 为什么 nodeName 有时在 javascript DOM 中全部大写?

jquery - 如何将Backbone模型绑定(bind)到jqGrid?

javascript - JavaScript 是否有 Money 类?

IOS - 如何在 Core Data Swift 中将数据插入具有关系的不同表中

javascript - DialogFlow v2 访问 token 无法生成

javascript - 从多个 div 标签中选择特定元素作为点击事件主干

javascript - 如何在获取 POST 请求中传递空值

javascript - 使用 fetch api 远程加载 md 文件并在客户端/浏览器上解析它