У меня есть простая страница " авторы ", которая показывает список авторов.
У каждого автора, конечно, много книг, но на этой странице (и в 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 (нет ожидающего загрузчика на этой странице книги).
Как это сделать?
Если вы не хотите отображать лениво загруженные данные отношений (в специальном 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');
});
});
},
// ...
Есть несколько способов сделать это. Один из способов, который я предпочитаю, когда ленивые данные загрузки следующие:
Сначала я создаю компонент, который инкапсулирует отображение и загрузку моих данных. В вашем примере я бы назвал свою 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}}