我试图操纵骨干的fetch方法来处理一些非标准的api。 api的工作方式如下:
api/products/[page]?param1=val¶m2=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结构,如何在backbone的fetch命令中包含分页?
答案 0 :(得分:3)
您正走在正确的轨道上,因为Backbone可以使用函数的返回值作为其' url'值。我个人会做的是在集合上设置一个页面属性(通过类似this.page引用),并将其包含在url函数的输出中。
initialize: function() {
this.page = 1; // Or whatever the default should be
},
url: function() {
return '/api/products/ + this.page;
}
然后问题就出现了更新页面属性,这可以像&Products;商品指南-Collection.page = 2;'一样简单。就个人而言,我还会添加第二个fetch方法来包装页面更新并将其提取到单个方法调用中。
fetch2: function(page, options) {
if (page) {
this.page = page;
}
return this.fetch(options);
}
答案 1 :(得分:0)
您的代码只需几个注释。我认为您不需要在收藏夹中定义页码。根据MVC模式,它更适合Controller。集合只需获取参数并根据它返回一些数据。同时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并进行初始加载。然后你应该做的就是将页码传递给你的加载函数。
答案 2 :(得分: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
}
});
},
});