Angular 通用的 handleStatus 函数和 Primeng Message 奇怪的行为

问题描述 投票:0回答:1

我正在尝试像这样显示以下组件:

<p-messages
  [(value)]="messages"
  [enableService]="toastEnabled"
  [closable]="false"
></p-messages>

其中 toastEnabled 和 messages 都是在我的产品组件中声明的变量,如下所示:

export class ProductsComponent {
  cart$: Observable<Product[]> = this.store
    .select(selectCart)
    .pipe(tap((cart) => console.log(cart)));
  messages: Message[] = [];
  toastEnabled: boolean = false;
  products$: Observable<Product[]> = this.store
    .select(selectProducts)
    .pipe(tap((products) => console.log(products)));
  constructor(
    private walmartService: WalmartService,
    private store: Store<IAppState>
  ) {}

  private handleViewStatusAndToast<T>(
    selector: MemoizedSelector<IAppState, T>,
    descriptor: string
  ): void {
    const status$ = this.store.select(selector).pipe(
      skipWhile((status) => status !== FetchStatus.Loading),
      take(2)
    );

    status$
      .pipe(find((status) => status === FetchStatus.Loading))
      .subscribe(() => {
        this.toastEnabled = true;

        this.messages = [
          {
            severity: 'warn',
            summary: 'Loading',
            detail: `${descriptor} is loading...`,
          },
        ];
      });

    status$
      .pipe(find((status) => status === FetchStatus.Success))
      .subscribe(() => {
        this.toastEnabled = true;

        this.messages = [
          {
            severity: 'success',
            summary: 'Success',
            detail: `Successfully loaded ${descriptor}!`,
          },
        ];
      });

    status$
      .pipe(find((status) => status === FetchStatus.Failure))
      .subscribe((error) => {
        this.toastEnabled = true;

        this.messages = [
          { severity: 'error', summary: 'Error', detail: 'Error...' },
        ];
      });
  }

  ngOnInit(): void {
    this.handleViewStatusAndToast(selectCartStatus, 'cart');
    this.store.dispatch({ type: '[Products Component] Load Products' });
    this.store.dispatch({ type: '[Cart Component] Load Cart' });
  }

消息组件与文本一起显示,但它的颜色是红色,消息是“错误...”,这是最后的状态,这是不可能的,因为数据也在显示,所以不可能发生错误.

有人知道为什么吗?

旁注 - 有人知道这是不是 Primeng 是我应该关注的组件库吗?我刚刚回到 Angular,想知道我是否应该花时间学习另一个 Angular

angular primeng
1个回答
0
投票

首先,Observables 不是这样工作的。 但别担心,我在这里解释你应该如何重构你的handleViewSta...函数。

订阅

首先,当您订阅代码中的任何可观察对象时。除非有事件触发完成事件,否则订阅不会结束。 这意味着当你订阅一个 observable 时,你不愿意多次订阅同一个 observable。

异步

不要忘记可观察量是异步的。 async/await 与 observables 与 Promise

您的代码

这意味着您的函数不应多次订阅可观察的状态,因为您不想检索可能的不同状态,而只想检索每个产品或购物车或任何其他对象的一个状态。

skipWhile在这里完全没有意义。
根据 rxjs 文档,SkipWhile 运算符表示您仅返回“正在加载”类型的状态。

const status$ = this.store.select(selector);

status$.subscribe((status) => {
  this.toastEnabled = true;

  if (status === FetchStatus.Loading) {
    this.messages = [
      {
        severity: 'warn',
        summary: 'Loading',
        detail: `${descriptor} is loading...`,
      },
    ];
  } else if (status === FetchStatus.Success) {
    this.messages = [
      {
        severity: 'success',
        summary: 'Success',
        detail: `Successfully loaded ${descriptor}!`,
      },
    ];
  } else if (status === FetchStatus.Failure) {
    this.messages = [
      { severity: 'error', summary: 'Error', detail: 'Error...' },
    ];
  }
});

这是快速编写的代码,可以通过多种方式进行改进(例如使用 switch case,...)。

记住

因为 observable 是异步的,所以你必须确保在加载数据之前进行订阅。

为什么还要观察?

在您的代码中,我相信您正在尝试加载购物车及其产品。在这种情况下,正如我在异步选项卡中提到的,您愿意使用 Promise。

如果您想使用可观察的,请查看异步管道。它允许您在可观察对象仍在异步检索数据时显示数据。

您真正应该做的只是使用异步管道将我们的数据异步显示到您的视图中。

希望这能有所帮助;)。我强烈建议观看一些 fireship youtube 教程。 (下面有链接)

rxjs 可观察值指南 rxjs通过fireship快速启动

© www.soinside.com 2019 - 2024. All rights reserved.