Выпуск подписки Angular 8 Async Pipe - PullRequest
0 голосов
/ 04 октября 2019

Полный пример StackBlitz: https://stackblitz.com/edit/angular8-async-pipe

В шаблоне компонента приложения есть три идентичных компонента:

<app-loader></app-loader>
<app-progress></app-progress>
<app-spinner></app-spinner>

Каждый компонент отправляет свое собственное действие NgRx, которое запускает запрос Http с использованием NgRxэффекты и ждет его завершения:

import { Component, OnInit } from '@angular/core';

import { Store } from '@ngrx/store';

import { Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';

import { ActionsService } from '../../../services/actions.service';

import * as MockyActions from '../../actions/mocky.actions';

@Component({
  selector: 'app-spinner',
  templateUrl: './spinner.component.html'
})
export class SpinnerComponent implements OnInit {
  progress$: Observable<boolean>;

  constructor (
    private store: Store<any>,
    private actionsService: ActionsService) {}

  ngOnInit() {
    this.progress$ = this.actionsService
      .isInProgress(MockyActions.GetMockySpinner)
      .pipe(
        map(({status}) => status),
        tap((status) => console.log('GetMockySpinner: ', status))
      );

    this.store.dispatch(MockyActions.GetMockySpinner());
  }
}

В каждом компоненте, использующем Async Pipe, я хочу показать спиннер во время выполнения запроса Http:

<div class="text-center" *ngIf="!(progress$ | async); else progress">
  Spinner
</div>

<ng-template #progress>
  <div class="text-center">
    <span class="spinner spinner-sm"></span>
  </div>
</ng-template>

Но только спиннер в <app-spinner></app-spinner>компонент отображается во время выполнения запроса Http в этом случае. И если последовательность компонентов в шаблоне компонента приложения изменилась:

<app-loader></app-loader>
<app-progress></app-progress>
<app-spinner></app-spinner>
<app-loader></app-loader>

В этом случае компонент Spinner в <app-loader></app-loader> отображается во время выполнения запроса Http. Так что только последний компонент в шаблоне работает как положено.

Так что же изменилось с Async Pipe в Angular 8 или что я делаю не так?

Пример с полным стеком StackBlitz: https://stackblitz.com/edit/angular8-async-pipe

Ответы [ 2 ]

1 голос
/ 04 октября 2019

Вы не используете фактическое состояние и редуктор для своего приложения. NgRX требует, чтобы вы использовали как действия, так и редукторы. Проблема, с которой вы столкнулись, заключается в том, что к тому моменту, когда первые два компонента подписались на тему действий, это уже третье действие. Вы не слушаете действия, которые происходят в NgRX. Вместо этого вы наблюдаете за изменением вашего состояния действием.

Вот рабочий стек, который решает вашу проблему.

https://stackblitz.com/edit/angular8-async-pipe-xexehj?file=src%2Fapp%2Fapp.module.ts

Ниже приведена полезная документация. https://ngrx.io/guide/store/reducers https://ngrx.io/guide/store

0 голосов
/ 04 октября 2019

Что-то не так с вашим MockyActions.

Замените

this.progress$ = this.actionsService.isInProgress(MockyActions.GetMockyProgress)
...

и

this.progress$ = this.actionsService.isInProgress(MockyActions.GetMockyLoader)
...

На

this.progress$ = this.actionsService.isInProgress(MockyActions.GetMockySpinner)

и васпример работает отлично.

...