Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Backbone.js 主干基于来自另一个URL的JSON响应动态填充集合_Backbone.js_Backbone.js Collections - Fatal编程技术网

Backbone.js 主干基于来自另一个URL的JSON响应动态填充集合

Backbone.js 主干基于来自另一个URL的JSON响应动态填充集合,backbone.js,backbone.js-collections,Backbone.js,Backbone.js Collections,我通常是从事J2EE(servlet/ejb)框架和库的后端人员。对前端尤其是主干来说是全新的。因此,这个问题有点像是一个无意义的问题。如果您有任何关于这方面的意见/教程/示例,我将不胜感激。我将尽可能清楚、详细地解释我的目标/要求 这是我的第一个SO问题,因此,对于违反任何规则,我提前表示歉意 我有一个后端电子商务引擎,它公开RESTURL作为产品目录API的一部分。 API 1-/rest/repository/atg/commerce/catalog/ProductCatalog/prod

我通常是从事J2EE(servlet/ejb)框架和库的后端人员。对前端尤其是主干来说是全新的。因此,这个问题有点像是一个无意义的问题。如果您有任何关于这方面的意见/教程/示例,我将不胜感激。我将尽可能清楚、详细地解释我的目标/要求

这是我的第一个SO问题,因此,对于违反任何规则,我提前表示歉意

我有一个后端电子商务引擎,它公开RESTURL作为产品目录API的一部分。 API 1-/rest/repository/atg/commerce/catalog/ProductCatalog/product/。 API 1以产品列表作为单个JSON数组进行响应。这里有趣的一点是,它只为每个产品发送单独的RESTURL。样本响应:

{"product": [
  "http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod90004",
  "http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod90005",
  "http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod100027"
  "http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod70011",
  "http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod70013"
]}
{
  "dateAvailable": "2000-05-04 15:51:42.521",
  "displayName": "Warm Black Gloves ",  
  "longDescription": "Protects you from the elements and keeps you looking good, these durable gloves won't let you down.",
  "repositoryId": "prod90004"
}
API 2-产品ID即。 基本上是API 1响应中的单个产品URL之一 样本响应:

{"product": [
  "http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod90004",
  "http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod90005",
  "http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod100027"
  "http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod70011",
  "http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod70013"
]}
{
  "dateAvailable": "2000-05-04 15:51:42.521",
  "displayName": "Warm Black Gloves ",  
  "longDescription": "Protects you from the elements and keeps you looking good, these durable gloves won't let you down.",
  "repositoryId": "prod90004"
}
所需目标:如果API 1使用包含4个URL(即4个产品)的JSON数组进行响应,那么我需要在视图中显示4个产品的属性,以此类推。通过对API 2进行4次调用,可以检索attibutes;换句话说,对API 1中接收的URL发出4个请求

问题: 我已经研究了一些教程和示例。在这个特定的用例中,我不知怎么地找不到任何东西。我所看到的示例假设将有一个restapi,它将使用一个JSON数组进行响应,该数组在一个JSON响应中包含所有模型(本例中为产品)及其属性。然而,这里的情况并非如此,因为我必须首先调用API 1以获取产品URL列表,然后调用所有这些URL(在API 1的响应中检索)以获取相应模型的属性。因此,我不知何故无法决定如何定义模型、集合和url属性等

我尝试了以下几点:

(function ($) {

    var ProductView = Backbone.View.extend({

        tagName:"div",
        className:"bookContainer",
        template:$("#bookTemplate").html(),

        render:function () {
            console.log("inside render of ProductView");
            var tmpl = _.template(this.template); 
            this.$el.html(tmpl(this.model.toJSON())); 
            return this;
        }
    });

    var ProductModel = Backbone.Model.extend({

        defaults:{
            displayName:"displayName",
            longDescription:"longDescription",
            dateAvailable:"dateAvailable",
            repositoryId:"repositoryId",
        },

        initialize: function(){
            this.on("reset", this.renderModelView, this);
            this.fetch({
                reset:true,
                error:function () {
                    console.log(arguments);
                }
            });

        },

        renderModelView: function(){
            var that = this;
            new ProductView.render({
                    model: that
                });

        }
    });

    var ProductCollection = Backbone.Collection.extend({
        model: ProductModel,

        initialize: function(){
            this.on("reset", this.debugTempfunc, this);
            this.fetch({
                reset:true,
                error:function () {
                    console.log(arguments);
                }
            });
        },

        debugTempfunc: function(){
            console.log("collection length: "+this.length);
        }
    });

    var ProductURLModel = Backbone.Model.extend({   

        defaults:{
            product: "ProductCatalogProductURLs"
        }       

    });

    var ProductURLCollection = Backbone.Collection.extend({
        model: ProductURLModel,

        url: "http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product",

        initialize: function(){
            this.on("reset", this.populateModels, this);
            this.fetch({
                reset:true,
                error:function () {
                    console.log(arguments);
                }
            });
        },

        populateModels: function(){
            var ProductCollectionIns = new ProductCollection();

            var that = this;
            console.log("inside populateModels of ProductURLCollection: "+that);
            _.each(that.models[0].attributes.product,function(item){
                console.log("populateModels, item value: "+item);
                ProductCollectionIns.url=item;
                ProductCollectionIns.fetch();

            });

        }       

    });

    var ProductURLCollectionTestIns = new ProductURLCollection();

})(jQuery);
我的计划是首先将ProductURLCollection定义为URL设置为API 1的URL的集合。此集合将有一个单一模型ProductURLModel,其中将有n个ProductURLModel。。。n是API 1中检索到的URL数量,它也相当于产品数量。这表明现在我必须进行n次API2调用。为此,我决定创建另一个集合ProductCollection,其中包含n个ProductModel。ProductCollection的url属性将在迭代ProductURLCollection模型时动态设置,如下代码所示:

populateModels: function(){
            var ProductCollectionIns = new ProductCollection();

            var that = this;
            console.log("inside populateModels of ProductURLCollection: "+that);
            _.each(that.models[0].attributes.product,function(item){
                console.log("populateModels, item value: "+item);
                ProductCollectionIns.url=item;
                ProductCollectionIns.fetch();

            });

        }
有了这个,我希望每次更改ProductCollections的url时都能动态地创建n个ProductModel。但是,我得到了“错误:必须指定“url”属性或函数”。这是否意味着未设置ProductCollections url属性


我相信一定有一个更简单的方法来实现上述目标。希望您能提供任何解决方案或更好的实施方案。

让我解释一下主干网的AJAX系统是如何工作的,首先是一个
模型(但我会在一分钟内介绍
集合
)。简言之,主干网旨在让您能够:

var FooModel = Backbone.Model.extend({url: 'www.example.com'});

var someModel = new FooModel({id: 5});
someModel.fetch().done(function() {
    // Now someModel should be populated with the AJAX data for model #5
});
someModel.get('someAttribute'); // == 2
在幕后,当您调用
fetch
Backbone查找与
模型相关联的URL时会发生什么。由于您从未定义过一个(或
urlRoot
),因此会出现错误,因为主干网不知道在哪里进行AJAX调用

一旦您通过
url
属性告诉主干网在何处查找该类型模型的数据,主干网将调用“www.example.com/5”(因为该模型的
id
为5)。主干网将期望URL返回类似以下内容的响应:

{id: 1, someAttribute: 2, someOtherAttribute: 'spam'}
该JSON将成为someModel的属性,因此您可以执行以下操作:

var FooModel = Backbone.Model.extend({url: 'www.example.com'});

var someModel = new FooModel({id: 5});
someModel.fetch().done(function() {
    // Now someModel should be populated with the AJAX data for model #5
});
someModel.get('someAttribute'); // == 2
Collection
s的工作方式几乎相同,只是它们期望JSON响应:

[{id: 1, someAttribute: 2, someOtherAttribute: 'spam'},
 {id: 2, someAttribute: 55, someOtherAttribute: 'eggs'}]
它们将返回数组中的每个成员转换为
模型

正如您所猜测的,有一种比您的
populateModels
方法更简单的方法:如果您只遵循我描述的模式,您的集合应该会自动创建模型,而无需额外的努力。如果您确实需要自定义内容(例如,您希望将来自服务器的“foo”属性更改为“bar”属性),您可以覆盖
模型
集合
解析
方法,该方法获取“原始”AJAX数据并返回转换后的版本:

var someModel = new FooModel({
    id: 5,
    parse: function(raw) {
        raw.bar = raw.foo;
        delete raw.foo;
        return raw;
    }
});

希望有帮助。

您在浏览器控制台中检查过API 1的响应了吗?它显示了什么?