Jquery 将单个json文件拆分为两个模型和一个集合,其中包含主干和$.getJSON

Jquery 将单个json文件拆分为两个模型和一个集合,其中包含主干和$.getJSON,jquery,json,backbone.js,Jquery,Json,Backbone.js,我有一个名为products的JSON文件,需要拆分它 该文件的结构如下所示 var ProductType=Backbone.Model.extend({ defaults:{ id:"", name:'', longName:'' } }); return ProductType var Product=Backbone.Model.extend({ defaults:{ id:"",

我有一个名为products的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;
我设想我需要一个集合(因为我不想在json文件中读两遍)和两个模型(productType和product)

我正在考虑使用getJson命令来实现这一点。我确实有在集合中使用主干url的想法,但这似乎更适合于从restful 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);
          });





      }
非常感谢您的帮助


谢谢

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

  • 获取数据文件并将内容处理为“模型就绪”形式
  • 基于解析的数据实例化模型/集合
  • 一般的想法是将非主干类型的东西(即,解析一种笨拙的数据格式)远离您的模型和集合,直到它们以他们能够理解的格式出现。这会使它们保持整洁,并将代码中棘手的部分隔离在自己的空间中

    因此,对于第一步,您应该能够在以下方面做一些事情:

    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);
    
    var products = new ProductCollection(result.models)
    var productTypes = new ProductTypeCollection(result.modelTypes);
    
    parseResponse
    方法结束时(您需要完成它的实现),
    result
    变量现在包含一个产品类型列表。最后一步是创建
    productType
    product
    集合。假设您已经设置了相应模型的
    ProductCollection
    ProductTypeCollection
    集合,您可以按照以下方式“主干化”解析为
    result
    的数据:

    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);
    
    var products = new ProductCollection(result.models)
    var productTypes = new ProductTypeCollection(result.modelTypes);
    

    决定把它留在这里。。稍后将删除/编辑并保留答案,以便人们看到解决方案

    所以我的项目使用jqm、jquery、主干网和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;
    
    问题是两件事

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

    数据正在进入页面,但什么都没有发生

    视图的update函数中的console.log确实执行,因此我感到困惑

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

    $.getJSON('data/product.json', this.parseResponse).success(function(data, status, xhr) { 
    
    在路由器上的initialize函数上,但如果我这样做并调用result.prodTypes或this.result.prodTypes,它会说它作为另一个函数的一部分未定义,我可以确定如何调用它-目前它在show products操作上,但这会导致问题,因为我需要使用产品:[]在不同的地方,不想调用json两次


    谢谢

    谢谢-我会试一试的。。逻辑听起来比我想的要好得多。我会让你知道我怎么做然后接受答案-但是感谢你的时间我还有几个问题-你介意我把它们添加到一个新的票子上吗,因为这个评论区域太小了?