从 ngOnInit 调度操作时的 ExpressionChangedAfterItHasBeenCheckedError

Posted

技术标签:

【中文标题】从 ngOnInit 调度操作时的 ExpressionChangedAfterItHasBeenCheckedError【英文标题】:ExpressionChangedAfterItHasBeenCheckedError when dispatching action from ngOnInit 【发布时间】:2017-12-30 03:44:49 【问题描述】:

我在AppComponent 的构造函数中订阅ngrx 商店:

export class AppComponent 
    submenuItems: Observable<Array<INavigationBarItem>>;

    constructor(private store: Store<AppState>) 
        this.submenuItems = this.store.select<Array<INavigationBarItem>>((state: AppState) => state.submenu.items);
    

然后,我在其他组件的 ngOnInit 方法中分派一个动作,如下所示:

export class SearchPageComponent implements OnInit 
    constructor(private store: Store<AppState>)  

    ngOnInit(): void 
        this.store.dispatch(new SubmenuAction([
             title: 'Search', isActive: true ,
             title: 'New Group' 
        ]));
    

而这种交互的结果是ExpressionChangedAfterItHasBeenCheckedError 异常。如果我将 dispatch 调用移至子组件的构造函数,则不会引发错误,但我想知道这是否只是偶然。另外我不认为把它放在构造函数体中是一个好主意。

我的每个组件都需要有这个store.dispatch 调用——正如你所见,它的目的是生成一个子菜单数据,该数据会因页面而异。如何解决这个异常?

【问题讨论】:

您是否尝试在AppComponent 中实现OnInit,然后在ngOnInit() 中订阅ngrx 存储?在构造函数中是否有特殊需要?据我了解,在构造函数中执行业务逻辑并不总是最佳实践,您应该只将其用于 DI 目的 错误描述是什么?您可能想阅读这篇文章Everything you need to know about the ExpressionChangedAfterItHasBeenCheckedError error @OsmanCea - 是的,我试过了,错误是一样的。 我今天也遇到了同样的问题......将选择移到构造函数中解决了它,但这显然不是我想做的事情,只是暂时的。很确定这是一个错误...... @Maxime - 你的意思是“将调度转移到构造函数中”,对吧? :) 【参考方案1】:

将调度调用从 ngOnInit 移到构造函数对我有用。

export class SearchPageComponent implements OnInit 
constructor(private store: Store<AppState>)  
 this.store.dispatch(new SubmenuAction([
         title: 'Search', isActive: true ,
         title: 'New Group' 
    ]));


    ngOnInit(): void  

【讨论】:

【参考方案2】:

我遇到过几次这个问题,并认为这将是 Angular 区域管理的问题。我所做的更像是一个 hack,但也许它也解决了你的问题:

ngOnInit(): void 
    setTimeout(() => this.store.dispatch(new SubmenuAction([
         title: 'Search', isActive: true ,
         title: 'New Group' 
    ])), 0);

【讨论】:

以上是关于从 ngOnInit 调度操作时的 ExpressionChangedAfterItHasBeenCheckedError的主要内容,如果未能解决你的问题,请参考以下文章

在获取数据w / subscribe之后我发送动作时的无限循环

在 ngOnInit 中添加验证器时的 ExpressionChangedAfterItHasBeenCheckedError

Express.js 中删除 req.body 时的空对象

从 react-native-router-flux 事件调度操作到 redux

操作系统基础知识

React Redux:调度时的无限循环