我目前正在主干上开发一个博客 - 现在在此之前我创建的任何主干应用程序都相当小,因此我应该在应用程序初始化时获取所有集合,将其存储在集合中并将它们传递给我对使用的看法。
我面临着处理潜在的大量数据(博客文章)。我不认为在一次调用中加载所有数据是最好的主意。我想做的是创建分页,最初会请求 9 条记录,其中包含帖子计数和计数的当前页面,然后对于每个页面,我们对下一组数据等发出新请求。
请记住,我也在构建 Rest API,因此我对响应的格式没有任何限制。
我非常想仍然遵循主干中的集合概念来执行此操作 - 这可能吗?
如果有人以前做过此操作或有任何可以帮助我的想法,那么我将不胜感激。
最佳答案
你可以这样做:
var BlogPostsCollection = Backbone.Collection.extend({
url: function() {
return 'posts?page='+this.page;
},
fetch: function(options) {
this.page = options && options.page || 0;
return Backbone.Collection.prototype.fetch.apply(this, arguments);
},
parse: function(resp, options) {
var models = resp;
return _.map(models, function(model) {
model.page = options.page;
return model;
});
}
});
var BlogPostsView = Backbone.View.extend({
syncedPages: [],
events: {
'click .page': 'onPageClick'
},
initialize: function() {
this.filteredCollection = new Backbone.Collection();
this.listenTo(this.collection, 'request', this.onCollectionRequest);
this.listenTo(this.collection, 'sync', this.onCollectionSync);
this.listenTo(this.filteredCollection, 'reset', this.onFilteredCollectionReset);
this.requestingPage = 0;
this.collection.fetch({
page: this.requestingPage
});
this.render();
},
onPageClick: function(e) {
e.preventDefault();
this.requestingPage = +e.target.dataset.page;
if (this.syncedPages.indexOf(this.requestingPage) < 0) {
this.collection.fetch({
page: this.requestingPage,
remove: false // Important - merge the response models
});
} else {
this.filterToPage(this.requestingPage);
}
},
onCollectionRequest: function() {
this.filteredCollection.reset();
this.render();
},
onCollectionSync: function(collection, response, options) {
if (options.page === this.requestingPage) {
this.filterToPage(this.requestingPage);
}
this.syncedPages.push(options.page);
},
onFilteredCollectionReset: function() {
this.render();
},
filterToPage: function(page) {
this.currentPage = page;
this.filteredCollection.reset(this.collection.where({ page: page }));
},
render: function() {
if (!this.filteredCollection.length) {
this.$el.html('<p>Loading...</p>')
} else {
this.$el.empty();
this.filteredCollection.each(function(postModel) {
this.$el.append('<p>'+postModel.get('title')+'</p>');
}, this);
}
this.$el.append('<a href="#page0" class="page" data-page="0">Page 0</a> | <a href="#page1" class="page" data-page="1">Page 1</a>');
}
});
var blogPostView = new BlogPostsView({
el: $('#app'),
collection: new BlogPostsCollection()
});
显然,该 View 用于演示目的 - 使用 html 字符串,逐一附加博客文章并不是最佳选择,应该有一个 BlogPostView 和一个 BlogNavigationView 等。
注意我添加了一些奖励逻辑:
- 抓取页面后,不需要重新抓取它(remove:false +syncedPages)
- 如果发生多个请求,它不会对显示哪个请求感到困惑(由于 requestingPage 变量)。如果您点击第 1 页,然后返回第 0 页,它会立即再次显示第 0 页,但会在后台缓存第 1 页。
关于javascript - BackboneJs 集合和 Rest API 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33654866/