首页 > 解决方案 > ngrx 动作触发 ExpressionChangedAfterItHasBeenCheckedError 异常

问题描述

我正在启动一个使用 ngrx 进行状态管理的 Angular 应用程序,我遇到了一个让我有点困惑的问题:

UI 操作之一是使用加载程序阻止屏幕,还有另一个取消阻止它:

import { createAction } from "@ngrx/store";

export const blockUI = createAction("[UI] Block UI");

export const unblockUI = createAction("[UI] Unblock UI");

true关联的 reducer 仅在操作之间或false取决于操作触发标志:

export const uiReducer = createReducer<UiState>(initialState,
  ...

  on(blockUI, (state) => ({ ...state, blockUi: true })),

  on(unblockUI, (state) => ({ ...state, blockUi: false })),

  ...

我在主应用程序的组件中订阅此状态标志以显示/隐藏 UI 阻止程序:

  this.store.pipe(
    select((state) => state.ui.blockUi),
    distinctUntilChanged()
  ).subscribe(
    (blockUi) => {
      console.log("Block UI: ", blockUi);
      this.loading = blockUi;
    }
  );

我正在使用distinctUntilChangedrxjs 运算符来丢弃相等的标志值,因为可以同时从多个组件分派阻止/解除阻止操作:

用户界面操作

这是 HTML 模板中阻止 UI 的组件(我使用 PrimeNG BlockUI):

  <!-- Component to block/unblock the UI -->
  <p-blockUI [blocked]="loading">
    <div class="divCenterHV">
      <p-progressSpinner></p-progressSpinner>    
    </div>
  </p-blockUI>

在我看来,一切都应该正常,但是当我运行应用程序时,我收到以下错误:

例外

我可以很容易地delay(1)在状态订阅中添加一个 rxjs 运算符来解决它,但我想知道为什么会触发异常,因为我找不到原因......

非常感谢!

标签: angularrxjsngrx

解决方案


这不是你如何对动作做出反应的问题,而是你何时分派动作的问题。调度可能发生在已经检查了一些代码之后(在父组件中的某个地方),可能在 ngOnInit 或 ngOnChanges 中,或者它对输入做出反应。很难说,因为您没有包含您发送的代码,但我确信这是问题所在。


推荐阅读