0

我有一个名为 products 的 JSON 文件,需要拆分它。

这个文件的结构是这样的

我设想我需要一个集合(因为我不想在 json 文件中读取两次)和两个模型(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 的想法,但这似乎更适合从静态 API 而不是静态 json 文件获取数据时,这些假设是否正确?

无论如何,如果我确实走上了拥有两个模型和一个集合的路线,当您在集合中定义一个方法时,这将如何工作?

我会假设有这样的模型

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

在这种情况下,将问题分为两个步骤可能是有意义的:

  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变量现在包含产品类型列表。最后一步是创建productTypeproduct集合。假设您已经拥有ProductCollectionProductTypeCollection集合具有适当的模型集,您可以result按照以下方式“Backbone-ify”您解析成的数据:

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;

问题是两件事..

首先,主要是当我点击进入第二页时,它不会去那里......但它不会引发错误。

数据正在进入页面,但什么也没发生?

视图的更新功能中的 console.log 确实执行了,所以我很困惑。

第二个和一个次要的 - 我想包括

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

在路由器上的 initalize 函数上,但如果我这样做并调用 result.prodTypes 或 this.result.prodTypes 它说它未定义为另一个函数的一部分,我可以弄清楚如何调用它 - 目前它在显示产品上操作,但这会导致问题,因为我需要在不同的地方使用产品:[],并且不想调用 json 两次

谢谢

于 2012-12-07T04:17:48.260 回答