Библиотека
Сценарий
У нас есть массив Todo
экземпляров, которые мы получаем из удаленного места, и нам нужно дождаться, пока наш todoStore:EStore
загрузит их, прежде чем мы сможем получить к ним доступ.
Подход
Примечание. Начиная с версии 11.0.0 takeWhile(v=>v, true
теперь встроен в структуру EStore.observeLoading()
метода Slice. См. Подробности в последнем разделе.
Сначала постройте и наблюдайте за магазином:
const todoStore:EStore<Todo> = new EStore(); const todoStoreLoading$:Observable<boolean> = todoStore.observeLoading().pipe(takeWhile(v=>v, true));
Мы используем takeWhile
, чтобы пометить наблюдаемый поток как завершенный, когда todoStoreLoading$
излучает false
в первый раз. Второй аргумент switchMap
(true
) находится там, чтобы мы могли видеть, что observeLoading$
наблюдаемое испустило false
.
Также обратите внимание, что v=>v
это то же самое, что v=>v!=false
.
Некоторым фреймворкам (например, преобразователям Angular) необходимо, чтобы значение Observable
было помечено как completed
, и поэтому это делается.
Наблюдаемый todoStoreLoading$
будет генерировать true
по умолчанию, поэтому нам нужно переключить его на false, когда магазин загрузится. Ниже это смоделировано путем первой публикации [todo1, todo2]
, а затем пометки loading
как false
.
this.todoStore.postA([todo1, todo2]) this.todoStore.loading = false;
Наблюдайте, когда магазин загрузился, и используйте switchMap
, чтобы получить Observable<Todo>
экземпляр.
const todo$ = todoStoreLoading$.pipe( filter(loading => loading == false), switchMap((v) => { return of(todoStorefindOneByID(todo1.id)) })); }
Дизайн среза
Обратите внимание, что pipe(takeWhile(v=>v, true)
теперь встроен в дизайн Slice. Ниже представлена новая реализация:
Поэтому, когда, например, вы пишете преобразователь Angular вместо этого:
resolve( route: ActivatedRouteSnapshot) { const id = route.paramMap.get('id') return this.cs.loadingTopicStore$.pipe( takeWhile(loading => loading, true), switchMap(()=>of(this.cs.topicStore.findOneByID(id)) )) }
Делаем так:
resolve( route: ActivatedRouteSnapshot) { const id = route.paramMap.get('id') return this.cs.loadingTopicStore$.pipe( switchMap(()=>of(this.cs.topicStore.findOneByID(id)) )) }