【问题标题】:How to use store.filter / store.find with Ember-Data to implement infinite scrolling?如何使用 store.filter / store.find 和 Ember-Data 实现无限滚动?
【发布时间】:2014-01-15 01:20:44
【问题描述】:

这最初发布在讨论.emberjs.com 上。看: http://discuss.emberjs.com/t/what-is-the-proper-use-of-store-filter-store-find-for-infinite-scrolling/3798/2

但是这些天来,该网站的内容质量似乎越来越差,所以我希望 StackOverflow 可以拯救我。

意图:用 ember-data 构建一个页面,实现无限滚动。

背景知识:基于 ember-data 上的 emberjs.com api 文档,特别是 store.filter 和 store.find 方法(参见:http://emberjs.com/api/data/classes/DS.Store.html#method_filter)我应该能够设置模型挂钩到商店过滤器操作的承诺。 Promise 的响应应该是一个过滤的记录数组,它是一个由过滤函数过滤的存储中的项目数组,该函数假设每当新项目被推入存储时都会不断更新。通过将其与将商品推送到商店的 store.find 方法相结合,filteredRecordArray 应该会自动更新新商品,从而更新模型并导致新商品显示在页面上。

例如,假设我们有一个 Questions Route、Controller 和一个 Question 类型的模型。

App.QuestionsRoute = Ember.Route.extend({
    model: function (urlParams) {
        return this.get('store').filter('question', function (q) {
            return true;
        });
    }
});

然后我们有一个控制器,它带有一些调用 store.find 的方法,这可能由一些事件/动作触发,无论是检测滚动事件还是用户显式点击加载更多,不管这个方法是否会被调用加载更多问题。 示例:

App.QuestionsController = Ember.ArrayController.extend({
    ...
    loadMore: function (offset) {
        return this.get('store').find('question', { skip: currentOffset});
    }
    ...
});

以及渲染项目的模板:

...
{{#each question in controller}}
   {{question.title}}
{{/each}}
...

注意,使用这种方法,我们NOT必须向明确调用this.get('model').pushObjects(questions);的store.find承诺添加一个函数事实上,一旦你已经返回了一个过滤器,就尝试这样做记录数组到模型不起作用。要么我们手动管理模型的内容,要么让 ember-data 完成工作,我非常希望让 Ember-data 完成工作。 这是一个非常干净的 API;但是,它似乎不像我写的那样工作。根据文档,我看不出有什么问题。

使用 chrome 中的 Ember-Inspector 工具,我可以看到来自第二个 find 调用的新问题已加载到“问题”类型下的商店中,但在我更改路线并返回之前页面不会刷新。看起来这只是观察者的问题,这让我认为这将是 Ember-Data 中的一个错误,但我不想贸然下这样的结论,直到我问我是否在使用 Ember-数据符合预期。

如果有人不知道到底出了什么问题,但知道如何使用 store.push/pushMany 在 jsbin 中重新创建此场景,这也会有所帮助。我只是不熟悉如何在商店中使用较低级别的方法。

非常感谢您的帮助。

【问题讨论】:

    标签: ember-data


    【解决方案1】:

    我只是让这个模式为自己工作,但是以“传统”方式,即不使用 store.filter()。

    我在路由器本身管理“loadMore”部分:

    actions: {
        loadMore: function () {
            var model = this.controller.get('model'), route = this;
            if (!this.get('loading')) {
                this.set('loading', true);
                this.store.find('question', {offset: model.get('length')}).then(function (records) {
                    model.addObjects(records);
                    route.set('loading', false);
                });
            }
        }
    }
    

    由于您已经尝试过传统方式(从我在讨论的帖子中看到的),看来关键部分是像您一样使用 addObjects() 而不是 pushObjects()。

    为了记录,这里是我的视图中触发 loadMore 动作的相关部分:

    didInsertElement: function() {
        var controller = this.get('controller');
        $(window).on('scroll', function() {
            if ($(window).scrollTop() > $(document).height() - ($(window).height()*2)) {
                controller.send('loadMore');
            }
        });
    },
    willDestroyElement: function() {
        $(window).off('scroll');
    }
    

    我现在希望将加载属性移动到控制器,以便为用户获得一个不错的加载器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-18
      • 2017-08-16
      • 1970-01-01
      • 2017-03-26
      • 2018-07-30
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      相关资源
      最近更新 更多