Подтвердить что ты не робот

Бесконечный свиток с ember.js(ленивая загрузка)

У меня есть представление, где может быть большое количество элементов для прокрутки пользователя, и я хотел бы реализовать бесконечную прокрутку, чтобы обеспечить прогрессивную загрузку содержимого.

Похоже, что некоторые люди сделали разбивку на страницы, но Google не вызывает никого, кто обсуждает, как они делали бесконечные списки с данными Ember/Ember. Кто-нибудь уже работал над этим и имеет код для публикации в блоге/пример для совместного использования?

4b9b3361

Ответ 1

Вы знали о недавно выпущенном компоненте Ember.ListView?

https://github.com/emberjs/list-view

Это было объявлено на февральском собрании в Сан-Франциско. Здесь slidedeck от Эрика Брина, одного из разработчиков Ember Core об использовании его:

http://talks.erikbryn.com/ember-list-view/

Ответ 2

Я реализовал бесконечный механизм прокрутки в проекте GitHub Dashboard , который я сейчас разрабатываю. Функция добавлена ​​в commit 68d1728.

Основная идея состоит в том, чтобы иметь LoadMoreView, который вызывает метод loadMore на контроллере каждый раз, когда вид виден в текущем окне просмотра. Для этого я использую плагин jQuery inview. Он позволяет вам регистрироваться для события inview, которое запускается, когда элемент указанного селектора отображается на экране и когда он исчезает.

Контроллер также имеет свойства, указывающие, есть ли больше загружаемых товаров, и если в данный момент есть элементы. Эти свойства называются canLoadMore и isLoading.

LoadMoreView в основном выглядит следующим образом:

App.LoadMoreView = Ember.View.extend({
  templateName: 'loadMore',
  didInsertElement: function() {
    var view = this;
    this.$().bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
      if (isInView) Ember.tryInvoke(view.get('controller'), 'loadMore');
    });
  }
});

где шаблон loadMore определяется следующим образом:

{{#if isLoading}}
    fetching some more stuff <img width="10" src="img/ajax-loader.gif" >
{{else}}
    {{#if canLoadMore}}
        <a {{action "loadMore" target="controller" }}>click to load more items</a>
    {{else}}
        <i>no more items</i>
    {{/if}}
{{/if}}

Затем контроллер, который обрабатывает выборку большего количества элементов, реализуется следующим образом. Обратите внимание, что в методе loadMore выполняется запрос в хранилище, который загружает определенную страницу записей для модели.

App.EventsController = Ember.ArrayController.extend({
  currentPage: 1,

  canLoadMore: function() {
    // can we load more entries? In this example only 10 pages are possible to fetch ...
    return this.get('currentPage') < 10;
  }.property('currentPage'),

  loadMore: function() {
    if (this.get('canLoadMore')) {
      this.set('isLoading', true);
      var page = this.incrementProperty('currentPage');

      // findQuery triggers somehing like /events?page=6 and this
      // will load more models of type App.Event into the store
      this.get('store').findQuery(App.Event, { page: page });
    } else {
      this.set('isLoading', false);
    }
  }
});

Осталось только сначала установить content контроллера на результат функции filter, поэтому content обновляется при загрузке новых моделей в магазин (что происходит из-за findQuery в loadMore контроллера). Кроме того, при вызове filter добавляется хэш query. Это гарантирует, что будет выполнен первоначальный запрос на сервер.

App.eventsController = App.EventsController.create({
    content: []
});

var events = App.store.filter(App.Event, { page: 1 }, function(data) {
    // show all events; return false if a specific model - for example a specific
    // type of event - shall not be included
    return true;
});

Ответ 4

Я бы рекомендовал использовать Ember Infinity. Он поддерживает Ember от 1.10 до 2.0 +.. Он относительно прост в настройке. Вам нужно только изменить маршрут и шаблон.

Маршрут (Product - пример модели):

import InfinityRoute from 'ember-infinity/mixins/route';

export default Ember.Route.extend(InfinityRoute, {
  model() {
    /* Load pages of the Product Model, starting from page 1, in groups of 12. */
    return this.infinityModel('product', { perPage: 12, startingPage: 1 });
  }
});

Шаблон:

{{#each model as |product|}}
  ...
{{/each}}

{{infinity-loader infinityModel=model}}

Когда компонент {{infinity-loader}} становится видимым, он отправляет действие на ваш маршрут, поэтому он знает обновить массив модели новыми (извлеченными) записями.

Первый запрос будет отправлен по адресу:

/products?per_page=12&page=1

Таким образом, вам также необходимо подготовить свой API-интерфейс для обработки этих параметров запроса. Он, очевидно, настраивается, взгляните на раздел расширенного использования Readme.

Примечание

Оба с использованием ListView (@commadelimited answer) и представления с ArrayController (ответ @pangratz) устарели/удалены, поскольку версия Ember 2.0 является стабильной версией.