将Backbone用于过滤服务器上的集合的服务是否存在常见模式?我无法在Google和Stack Overflow搜索中找到任何内容,考虑到正在生产的Backbone应用程序的数量,这是令人惊讶的。
假设我正在使用Backbone构建Stack Overflow的新前端。
在搜索屏幕上,我需要将以下信息传递给服务器并返回一页值得的结果。
Backbone似乎对将过滤卸载到服务器没有太大兴趣。它希望服务器返回整个问题列表并在客户端执行过滤。
我猜测为了完成这项工作,我需要继承Collection并覆盖fetch方法,以便不是总是从同一个RESTful URL获取数据,而是传递上述参数
我不想重新发明轮子。我是否缺少Backbone中的一项功能,可以使此过程更简单或与现有组件更兼容?是否已经有一个完善的模式来解决这个问题?
答案 0 :(得分:3)
如果您只想在请求中传递GET参数,您应该只能在fetch调用本身中指定它们。
collection.fetch( {
data: {
sortDir: "ASC",
totalResults: 100
}
} );
传递给fetch的选项应直接转换为jQuery.ajax调用,并且应自动解析数据属性。当然,覆盖fetch方法也很好,特别是如果你想要标准化部分逻辑。
答案 1 :(得分:1)
你是对的,创建自己的Collection
是可行的方法,因为除了OData之外没有关于服务器分页的标准。
而不是覆盖'fetch',我通常在这些情况下做的是创建一个collection.url
属性作为函数,根据集合状态返回正确的URL。
但是,为了进行分页,服务器必须向您返回项目总数,以便您可以计算每页基于X项目的页数。现在有些API使用HAL或HATEOAS之类的东西,它们基本上都是HTTP响应头。为了获得该信息,我通常会在sync
事件中添加一个侦听器,该事件是在任何AJAX操作之后引发的。如果您需要通知可用项目/页面数量的外部组件(通常是视图),请使用事件。
简单示例:您的服务器在响应头中返回X-ItemTotalCount
,并且在请求查询字符串中需要参数page
和items
。
var PagedCollection = Backbone.Collection.extend({
initialize: function(models,options){
this.listenTo(this, "sync", this._parseHeaders);
this.currentPage = 0;
this.pageSize = 10;
this.itemCount = 0;
},
url: function() {
return this.baseUrl + "?page=" + this.currentPage + "&items=" + this.pageSize;
},
_parseHeaders: function(collection,response){
var totalItems = response.xhr.getResponseHeader("X-ItemTotalCount");
if(totalItems){
this.itemCount = parseInt(totalItems);
//trigger an event with arguments (collection, totalItems)
this.trigger("pages:itemcount", this, this.itemCount);
}
}
});
var PostCollection = PagedCollection.extend({
baseUrl: "/posts"
});
请注意,我们使用另一个自己的属性baseUrl
来简化对PagedCollection的扩展。如果您需要添加自己的initialize
,请像这样调用父级的原型,或者您不会解析标题:
PagedCollection.protoype.initialize.apply(this,arguments)
您甚至可以将fetchNext
和fetchPrevious
方法添加到集合中,只需修改this.currentPage
和fetch
即可。如果您想将一个页面替换为另一个页面而不是附加,请务必将{reset:true}
添加为fetch
选项。
现在,如果项目的后端是一致的,那么在服务器上允许分页的任何资源都可以使用客户端上的一个基于PagedCollection的集合来表示,前提是使用了相同的参数/响应。