Библиотека



Сценарий

У нас есть массив 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))
    ))
}