javascript - BackboneJs 集合和 Rest API 调用

标签 javascript php jquery backbone.js require

我目前正在主干上开发一个博客 - 现在在此之前我创建的任何主干应用程序都相当小,因此我应该在应用程序初始化时获取所有集合,将其存储在集合中并将它们传递给我对使用的看法。

我面临着处理潜在的大量数据(博客文章)。我不认为在一次调用中加载所有数据是最好的主意。我想做的是创建分页,最初会请求 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 页。

演示:http://jsfiddle.net/ferahl/sfyqt7wr/

关于javascript - BackboneJs 集合和 Rest API 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33654866/

相关文章:

php 5.3 fwrite() expects parameter 1 to be resource 错误

php - 通过添加后缀重命名文件

javascript - 如何在我的 jquery 菜单中的 li 项下添加一行?

javascript - 这个javascript在语法上是正确的还是有更好的方法?

javascript - 如何确保 php 脚本不会运行两次

jquery - 带 Razor 的 MVC : how to refresh partial page on click?

javascript - 在 Ipad 或触摸设备上播放多个音频

javascript - MeteorJS 和 PDF 生成

javascript - Vue.js 转换不适用于页面首次加载

php - 我应该将 Unix 时间戳转换为 "hour"时间戳吗?