Каково ваше мнение о том, что управление состоянием контролируется касаниями (побочными эффектами в подписке)?
Какие плюсы или минусы вы видите в этом случае?
Я мог бы представить трудности с тестированием, но не обязательно больше, чем когда вы просто подписываетесь на параметры маршрута и устанавливаете состояние в ngInit
Менее понятно, почему, например, для выдачи null требуетсяпоследний шаг по сравнению с более явным isLoading=true
?
this.CurrentItem$ = this.route.queryParamMap
.pipe(
pluck('id'),
// Navigate to main page if no id given
tap((id: string) => !!id || this.router.navigate(['/'])),
// And cancel the rest of the pipe
filter((id: string) => !!id),
// More filtering
distinctUntilChanged(),
// Convert to int (for example purposes)
map((id: string) => +id),
// Set controller state, aka side effects
tap((id: number) => {
this.CurrentIndex = id;
}),
// more side effects ?! Preload from cache this and the next ten
tap((curIdx: number) =>
{
for (let i = curIdx; i < curIdx + 10; i++) { // ignoring sanity checks now
this.dataCache[i] = this.dataCache[i] || this.http('http://get' + i);
}
}),
// More side effects to set buttons states (go next, go previous)
tap((curIdx: number) => {
this.LinkNext = curIdx < 100 ? "/bla/" + curIdx+1 : null;
this.LinkPrev = curIdx > 0 ? "/bla/" + curIdx-1 : null;
}),
// Switch to the actual data.
// of(null) is returned immediately, while datacache is http request that can take a while
// hence the null resets currentItem|async to null in ngIf and makes the loading progress bar displayed
switchMap((curIdx: number) => merge(of(null), this.dataCache[curIdx]))
);
HTML может выглядеть так:
<ng-container *ngIf="CurrentItem$ | async as item; else loading">
{{ item | json }}
<a *ngIf="LinkNext" [routerLink]="LinkNext"> Next item </a>
</ng-container>
<ng-template #loading>
Loading ...
</ng-template>