0

products という単一の JSON ファイルがあり、これを分割する必要があります。

このファイルの構造はこのようなものです

1 つのコレクション (json ファイルを 2 回読みたくないため) と 2 つのモデル (productType と product) が必要であると想定しています。

productTypeList
   0
     id
     name
     productList
       0
         id
         name
       1
         id
         name
       2
         id
         name
       3
         id
         name
   1
     id
     name
     productList
   2
     id 
     name
     productList

これを行うには getJson コマンドを使用することを考えていました。コレクション内でバックボーン URL を使用するというアイデアを試してみましたが、これは、データが静的 json ファイルではなく安静な API から取得されている場合により適しているようです。これらの仮定は正しいでしょうか?

とにかく、2 つのモデルと 1 つのコレクションを持つルートをたどると、コレクションでメソッドを定義するときにどのように機能しますか?

私はこのようなモデルを持っていると思います

var ProductType=Backbone.Model.extend({
    defaults:{
        id:"",
        name:'',
        longName:''

    }
});

return ProductType

var Product=Backbone.Model.extend({

    defaults:{
        id:"",
        name:'',
        ordering:'',
        introSmall:'',
        introNormal:'',
        sellingPoints:'',
        interestRate:'',
        interestRateLabel:''
        productTypeID:''

    }
});

return Product;

そして、コレクションがどのように機能するかわかりません...コメント/質問を追加しましたか?

var Products=Backbone.Collection.extend({

      // Do i call both models here??
      model:ProductType,
      model:Product,

      fetch:function(){
        var self=this;
        var tmpItem;
        var tmpProduct

           var jqxhr = $.getJSON("data/product.json")
          .success(function(data, status, xhr) { 

            $.each(data.productTypeList, function(i,item){

              tmpItem=new ProductType({


        id:item.id,
            name:item.name,
            longName:item.longName,
            ordering:item.ordering
                });

                     $.each(data.productTypeList[i], function(a,itemProduct){

                     tmpProduct = new Product ({
                     id:itemProduct.id,
             name:itemProduct.name,
             ordering:itemProduct.ordering,
             introSmall:itemProduct.introSmall,
                         productTypeID:i
                     });

                    self.add(tmpProduct);

                     });


              self.add(tmpItem);

            });
            //dispatch customized event
            self.trigger("fetchCompleted:Products");

          })
          .error(function() { alert("error"); })
          .complete(function() {
                console.log("fetch complete + " + this);
          });





      }

どんな助けでも本当に感謝しています

ありがとう

4

2 に答える 2

2

この場合、問題を 2 つのステップに分割することが理にかなっている可能性があります。

  1. データ ファイルを取得し、コンテンツを「モデル対応」形式に処理する
  2. 解析されたデータに基づいてモデル/コレクションをインスタンス化します。

一般的な考え方は、モデルやコレクションが理解できる形式になるまで、非バックボーン タイプのもの (つまり、ぎこちないデータ形式の解析) をモデルやコレクションから遠ざけることです。これにより、コードがきれいに整頓された状態に保たれ、コードのトリッキーな部分が独自のスペースに分離されます。

したがって、最初のステップとして、次の行で何かを実行できる必要があります。

var parseResponse = function (data) {

  var result = { types: [], models: [] };

  var type, 
      types = data.productTypeList,
      product,
      i = types.length;

  while (type = types[--i]) {
    result.types.push({ 
       id: type.id,
       name: type.name
       // etc.
    });
    while (product = type.productList.pop()) {
      product.productTypeId = type.id;
      result.models.push(product);
    }
  }
};

$.getJSON('...', parseResponse);

メソッドの終わりまでにparseResponse(実装を完了する必要があります)、result変数には製品タイプのリストが含まれています。最後の仕上げは、productTypeおよびproductコレクションの作成です。ProductCollection適切なモデルが設定されたコレクションがあると仮定すると、次の行に沿っProductTypeCollectionて解析したデータを「バックボーン化」できます。result

var products = new ProductCollection(result.models)
var productTypes = new ProductTypeCollection(result.modelTypes);
于 2012-12-07T02:14:02.193 に答える
0

ここに保存することにしました..後で削除/編集し、回答を保持して、人々が解決策を確認できるようにします

私のプロジェクトはjqm、jquery、backbone、requireを使用しています

ルーティングを行わないようにjqmをセットアップし、バックボーンで処理できるようにしました

私のルーターページで私は持っています

var AppRouter = Backbone.Router.extend({

routes: {
        '':    'showHome',         //home view
        'home': 'showHome',        //home view as well
        'products/productList' : 'showProducts',

        '*actions': 'defaultAction' 
    },

initialize:function () {
    // Handle back button throughout the application
    $('.back').live('click', function(event) {
        window.history.back();
        return false;
    });
    this.firstPage = true;
},


parseResponse : function(data) {

 result = { prodTypes: [], products: [] };
       var type;
   var types = data.data.productTypeList;
   var product;
   var i = types.length;


            while (type = types[--i]) {
            result.prodTypes.push({ 
               id: type.id,
               name: type.name,
               longName: type.longName

            });
            while (product = type.productList.pop()) {
              product.productTypeId = type.id,
              result.products.push(product);
            }
          }


    },


    defaultAction: function(actions){
        this.showHome();
    },

    showHome:function(actions){
        // will render home view and navigate to homeView
        var homeView=new HomeView();
        homeView.render(); 

        this.changePage(homeView, 'fade');
    },



    showProducts:function(){

        $.getJSON('data/product.json', this.parseResponse).success(function(data, status, xhr) { 


     var productList=new Products(result.prodTypes);
     var productListView=new ProductListView({collection:productList});

     productListView.bind('renderCompleted:Products',this.changePage,this);

     productListView.update();

       });   


    },

    changePage:function (view, transition) {
        //add the attribute 'data-role="page" ' for each view's div

        console.log("pagechanged");
        if (transition != "slidefade") {
         transition = "pop";                
        }

        view.$el.attr('data-role', 'page');   
        $('.ui-page').attr('data-role', 'page');

        //append to dom
        $('body').append(view.$el);  


        if(!this.init){   
            $.mobile.changePage($(view.el), {changeHash:false, transition: transition});


        }else{   
            this.init = false;
        }            
    }       

});

$(document).ready(function () {
console.log('App Loaded');
app = new AppRouter();
Backbone.history.start();
});

return AppRouter;

私のコレクションページ

        var Products=Backbone.Collection.extend({

      // Book is the model of the collection
      model:ProductType,


      //fetch data from books.json using Ajax 
      //and then dispatch customized event "fetchCompleted:Books"
      fetch:function(){
        var self=this;
        var tmpItem;
        var tmpProduct;
        //fetch the data using ajax

        $.each(result.prodTypes, function(i,prodType){

            tmpItem=new ProductType({id:prodType.id,    name:prodType.name, longName:prodType.longName});

            self.add(tmpItem);
        });

        self.trigger("fetchCompleted:Products");  
      }
});

return Products;

私の閲覧ページ

  var ProductListView = Backbone.View.extend({

template: _.template(productViewTemplate),

update:function(){
  //set callback of the event "fetchCompleted:Products" 
  this.collection.bind('fetchCompleted:Products',this.render,this);
  this.collection.fetch();
  console.log(this.collection);
},

render: function(){
  this.$el.empty();
  //compile template using the data fetched by collection
  this.$el.append(this.template({data:this.collection.toJSON()}));
  this.trigger("renderCompleted:Products",this);

  return this;
}
});

return ProductListView;

問題は2つのことです..

まず、主にクリックして2番目のページに移動すると、そこには移動しません...しかし、エラーはスローされません。

データはページを通過していますが、何も起こっていませんか?

ビューの更新機能内の console.log が実行されるので、困惑しています。

2番目とマイナーなもの-含めたい

$.getJSON('data/product.json', this.parseResponse).success(function(data, status, xhr) { 

ルーターのinitialize関数についてですが、result.prodTypesまたはthis.result.prodTypesを呼び出して呼び出すと、別の関数の一部として未定義と表示され、それを呼び出す方法を理解できます-現時点ではショー製品にありますアクションですが、products: [] を diff の場所で使用する必要があり、json を 2 回呼び出したくないため、問題が発生します。

ありがとう

于 2012-12-07T04:17:48.260 に答える