2014-10-28 39 views
2

我想操縱主幹的提取方法來處理一些非標準的api。該API的工作方式如下:傳遞參數到主幹提取url來處理非標準api

api/products/[page]?param1=val&param2=val 

例如:

api/products/2?budget=low&categories=all 

就相當於得到結果的第二頁爲其預算低,所有類別都包括在內。

我可以通過格式的查詢字符串之後傳遞的參數就好了:

self.productsItemsCollection.fetch({ success : onDataHandler, dataType: "json", data: { budget: 'low', categories: 'all' } }); 

,但我不知道該怎麼做分頁,因爲它來自前?問號。

下面是如何收集設置:

define([ 
    'underscore', 
    'backbone', 
    'models/products/ProductsItemsModel' 
], function(_, Backbone, ProductsItemsModel){ 

    var ProductsItemsCollection = Backbone.Collection.extend({ 

     model: ProductsItemsModel, 

     initialize : function(models, options) {}, //MH - need to pass filters to this function 

     url : function() { 
     return '/api/products/'; //MH - need to pass page number to be appended to this url 
     }, 

     parse : function(data) { 
     debugger; 
     return data.items; 
     } 

    }); 

    return ProductsItemsCollection; 

}); 

我怎麼可以列舉出這個API URL結構骨幹獲取命令分頁?

回答

3

您正處在正確的軌道上,Backbone可以使用函數的返回值作爲其「url」值。我個人會做的是在集合上設置頁面屬性(通過類似this.page引用),並將其包含在url函數的輸出中。

initialize: function() { 
    this.page = 1; // Or whatever the default should be 
}, 
url: function() { 
    return '/api/products/ + this.page; 
} 

然後,問題就變成了更新頁面屬性,可能就像'ProductsItemsCollection.page = 2;'一樣簡單。就我個人而言,我還會添加第二個提取方法來將頁面更新和提取包裝到單個方法調用中。

fetch2: function(page, options) { 
    if (page) { 
    this.page = page; 
    } 
    return this.fetch(options); 
} 
+2

...但你(和每一個與你的代碼工作開發者)必須記住調用'fetch2'代替的提取。這是糟糕的編碼和容易出錯。相反,在你的模型中重寫fetch來設置頁面,然後調用超類的'fetch'實現。 – Madbreaks 2016-08-24 23:04:30

0

只是幾個註釋到您的代碼。我認爲你不需要在收藏中定義頁碼。根據MVC模式,它更適合Controller。 Collection只需要獲取參數並根據它返回一些數據。同時Backbone不提供經典的MVC控制器,但您可以爲此使用Backbone.View。所以,你的應用程序的結構可能看起來是這樣的:

// Collection 
    define([ 
     'backbone', 
     'models/products/ProductsItemsModel' 
    ], function(Backbone, ProductsItemsModel){ 

     return Backbone.Collection.extend({ 

     // I don't know what exactly your Model does, but if you don't override Backbone.Model with your own methods you don't really need to define it into your collection. 
     model: ProductsItemsModel, 

     initialize : function(models, options) {}, //MH - need to pass filters to this function 

     url : function(page) { 
     return '/api/products/' + page; 
     }, 

     parse : function(data) { 
     return data.items; 
     } 
    }); 
}); 

,然後在視圖中,您可以獲取所需的頁面,並使其:

define([ 
    'jquery', 
    'backbone', 
    'ProductsItemsCollection' 
], function($, Backbone, ProductsItemsCollection){ 

    return Backbone.View.extend({ 

     events: { 

      // Your logic to get page number from your pagination. 
      'click .pagination': 'getPageNumber' 
     } 

     collection: new ProductsItemsCollection(), 

     initialize : function() { 
      this.listenTo(this.collection, 'reset', this.render); 

      // initial loading collection 
      this.load(1); // load page #1 
     }, 

     render: function() { 
      // your render code 
     } 

     // Example function to show how you could get page number. 
     getPageNumber: function(e) { 
      var pageNumber = $(e.currentTarget).data('pageNumber'); 
      load(pageNumber); 
     }, 

     load: function(page) { 
      url: this.collection.url(page), 
      data: { 
       budget: 'low', 
       categories: 'all' 
      } 
     } 
    }); 
}); 

類似的東西。所以在這個視圖中,你只需要初始化你的Collection並進行初始加載。那麼你應該做的就是將頁碼傳遞給你的加載函數。

0

我看過這些答案,我猜這些答案是有道理的,但這是我一起去的。只是很簡單:

app.WorkOrder = Backbone.Collection.extend({ 
    model: app.WorkOrderDetail, 
    urlRoot: '/m2/api/w/', 
    getWorkOrder: function(workorder_id, options) { 
     this.url = this.urlRoot + workorder_id; 
     return this.fetch(options); 
    } 
}); 

然後在視圖我這樣做:

app.AppView = Backbone.View.extend({ 
    el: '#workorderapp', 
    initialize: function() { 
     app.workOrder.getWorkOrder(workorder_id, { 
      success:function(data) { 
       //...do something with data 
      } 
     }); 
    }, 
});