Ember.js 2. Ленивая выборка в фоновом режиме после рендеринга страницы

1

У меня есть простая страница " авторы ", которая показывает список авторов.

У каждого автора, конечно, много книг, но на этой странице (и в API) я не показываю (/include) никаких книжных данных.

На пути авторов у меня есть модель по умолчанию():

model() {
  return this.store.findAll('author');
}

и все в порядке.

Теперь мне нужно что-то, чтобы получить ленивые (в фоновом режиме) некоторые данные из других API (книги).

Но я не хочу, чтобы этот вызов блокировал мою страницу рендеринга авторов. Итак, у меня есть значение по умолчанию и beforeModel(), model() и afterModel() без какой-либо выборки (кроме данных авторов).

ТОЛЬКО после визуализации страницы мне нужно что-то (возможно, сервис?), api/books?author:1,2,3,4,5... вызывает " api/books?author:1,2,3,4,5... "

Таким образом, у меня уже есть книги в моем "магазине", когда кто-то нажимает на athor (нет ожидающего загрузчика на этой странице книги).

Как это сделать?

Теги:
ember.js
ember-data
lazy-loading
ember-cli

1 ответ

0

1. Если вы хотите лениво загружать и сохранять данные отношений без блокировки пользовательского интерфейса:

Если вы не хотите отображать лениво загруженные данные отношений (в специальном hasMany -relationships), я бы рекомендовал сделать это в afterModel -hook:

route.js:

  // ...

  afterModel(authors) {
    let lastPromise = new Promise(function(resolve) { resolve(); });
    authors.forEach(author => {
      lastPromise = lastPromise.then(() => {
        return author.get('books');
      });
    });
  },

  // ...        

2. Если вы хотите лениво загружать, сохранять и отображать данные отношений, не блокируя пользовательский интерфейс:

Есть несколько способов сделать это. Один из способов, который я предпочитаю, когда ленивые данные загрузки следующие:

Сначала я создаю компонент, который инкапсулирует отображение и загрузку моих данных. В вашем примере я бы назвал свою book-shelf.

После вставки в DOM мой компонент хочет отобразить свои книги. См. Следующий код.

component.js:

import Ember from 'ember';

const {
  get,
  computed,
  ArrayProxy,
  PromiseProxyMixin,
  inject: { service }
} = Ember;

const ArrayPromiseProxy = ArrayProxy.extend(PromiseProxyMixin);

export default Ember.Component.extend({
  // API:
  author: null,

  // Internal:
  store: service(),
  books: computed(
    'author.id',
    function() {
      if(!get(this, 'author.id')) {
        return [];
      }
      return ArrayPromiseProxy.create({
        promise: get(this, 'store').query('book', { authorId: get(this, 'author.id') })
      });
    }
  ),
});

И в вашем шаблоне.hbs:

<div class="book-shelf">
  {{#if books.isFulfilled}}
    Books of {{author.name}}:
    <ul>
      {{#each books as |book|}}
        <li>{{book.name}}</li>
      {{/each}}
    </ul>
  {{else}}
    Loading... please wait...
  {{/if}}
</div> 

Этот подход объединяет прокси-сервер массива с прокси-сервером обещания, чтобы действовать как массив, но также предоставляет информацию о том, загружены ли данные.

Вы можете использовать этот компонент как каждый компонент в ember.js:

{{book-shelf author=mySpecialAuthor}}
  • 0
    Большое спасибо @Timm, но мне это нужно не в DOM, не в компоненте. На странице авторов мне нужно (ТОЛЬКО ПОСЛЕ РЕНДЕРИНГА страницы авторов), чтобы в фоновом режиме получить данные книг. Таким образом, данные книги каждого автора готовы для клика по любому автору (и рендеринга страницы книги ...).
  • 0
    так что, возможно, новое добавленное «первое» решение подойдет вам?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню