2014-10-06 2 views
0

저는 일반적으로 J2EE (servlet/ejb) 프레임 워크 및 라이브러리에서 작업하는 백엔드 사용자입니다. 프론트 엔드와 특히 백본에 완전히 새로 도입되었습니다. 그러므로 질문은 다소 멍청한 질문이다. 그 문제에 대한 모든 의견/자습서/예제를 부탁드립니다. 내 목표/요구 사항을 가능한 명확하고 정교하게 설명하려고 노력할 것입니다.다른 URL의 JSON 응답을 기반으로 동적으로 콜렉션을 채우는 백본

이것은 내 첫 번째 질문이므로 모든 규칙을 위반하여 사전에 사과드립니다.

Q. 제품 카탈로그 API의 일부로 REST URL을 제공하는 백엔드 전자 상거래 엔진이 있습니다. API 1 -/rest/repository/atg/commerce/catalog/ProductCatalog/product /. API 1은 제품 목록을 단일 JSON 배열로 응답합니다. 여기서 흥미로운 점은 각 제품에 대해 개별 REST 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" 
]} 

API 2-http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/productId에 즉. http://example.com/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod90004 API (1)의 응답 샘플 응답에서 개별 제품 URL의 기본적으로 하나

{ 
    "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 개 제품보기. attibutes는 API 2를 4 번 호출하여 검색 할 수 있습니다. 즉 API 1에서받은 URL에 대해 4 회의 요청을합니다.

문제 : 몇 가지 자습서와 예제를 살펴 보았습니다. 이 특정 사용 사례에서 어떻게 든 얻을 수 없었습니다. 필자가 보았던 예제에서는 모든 모델 (이 경우 제품)과 하나의 JSON 응답에있는 특성을 포함하는 JSON 배열로 응답하는 하나의 REST API가 있다고 가정합니다. 그러나 먼저 제품 URL 목록을 가져온 다음 API 1의 응답에서 검색된 이러한 모든 URL을 호출하여 해당 모델의 특성을 가져와야 API 1을 호출해야합니다.

(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 속성 등을 정의하는 방법에 관한 결정에 어떻게 든 할 수 없습니다입니다 URL이 API 1의 URL로 설정된 모음으로 이 컬렉션에는 ProductURLModel이라는 단일 모델이 있으며 ProductURLModel (n) 개의 숫자가 있습니다. n은 API 1에서 검색된 URL의 수이며 이는 제품 수와 같습니다. 이것은 이제 n 개의 API 2 호출을해야한다는 것을 나타냅니다. 이를 위해 n 개의 ProductModel (s)을 포함하는 다른 Collection ProductCollection을 만들기로했습니다. 내가 만들 n은 ProductModel (들)마다 동적으로 변화하는 ProductCollectionIns의 URL을 수 있다는 희망이와

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(); 

      }); 

     } 

를 아래 코드와 같이 'ProductURLCollection 모델을 반복하면서 ProductCollection의 url 속성을 동적으로 설정됩니다. 그러나 "오류 : A"URL "속성 또는 기능을 지정해야합니다."가 표시됩니다. ProductCollectionIns url 속성이 설정되지 않았다는 의미입니까?

위의 백본을 구현하는 더 쉬운 방법이 있어야한다고 생각합니다. 제발 솔루션이나 더 나은 구현을 주시면 감사하겠습니다.

+0

브라우저 콘솔에서 API 1의 응답을 확인 했습니까? 그것은 무엇을 보여줍니까? – booleanhunter

답변

0

먼저 백본의 AJAX 시스템이 작동하는 방식을 설명하겠습니다. 먼저 Model (단 Collection 초)입니다. 즉, 백본은 당신이 할 수 있도록 설계되었습니다 : 장면 뒤에

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 
}); 

fetch 백본이 Model과 관련된 URL을 찾습니다 호출 할 때이 어떻게되는지. 하나 (또는 ​​urlRoot)를 정의한 적이 없으므로 Backbone은 AJAX 호출을 수행 할 위치를 알지 못하므로 오류가 발생합니다.

url 속성을 통해 해당 유형의 데이터를 찾을 위치를 Backbone에게 알려주면 Backbone은 id이 5이므로 'www.example.com/5'를 호출합니다.

{id: 1, someAttribute: 2, someOtherAttribute: 'spam'} 

JSON은 someModel의 속성이 될 것이라고 당신이 할 수 있습니다 있도록 :

someModel.get('someAttribute'); // == 2 

Collection의 작업을 백본은 다음과 같이 보입니다 응답을 반환하기 위해 해당 URL을 기대 거의 같은 방식으로, 그들은의 JSON 응답을 기대 제외 :

[{id: 1, someAttribute: 2, someOtherAttribute: 'spam'}, 
{id: 2, someAttribute: 55, someOtherAttribute: 'eggs'}] 

을하고 그들이 Model에 반환 된 배열의 각 구성원을 변환합니다.

당신이 추측했듯이 populateModels 방법보다 쉬운 방법이 있습니다. 제가 설명한 패턴대로하면 컬렉션은 추가 노력없이 자동으로 모델을 만들어야합니다. 서버에서 오는 "foo"속성을 "bar"속성으로 변경하려는 경우와 같이 사용자 정의해야하는 경우 Model 또는 Collectionparse 메소드를 덮어 쓸 수 있습니다.이 메소드는 " 원시 "AJAX 데이터를 가져와 변환 된 버전을 반환합니다.

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

희망이 있습니다.