Angular2 change detection “Expression has changed

2019-02-20 22:59发布

I have an issue in Angular2 (final) around change detection and data flow between components. I have worked around it but it seems a little hacky to me so was wondering if there is a better way of doing it.

Basically I have a component A that has a child component B and also *ngFor that creates number of children components C.

For every component C, there is an @Output defined that is handled in the parent component A for each instance of C. Based on that output, another property on component A is determined (just a number) and thats used as @Input on component B.

In DEV mode, every time the @Output in components C is triggered, I am getting below error in the console:

Expression has changed after it was checked. Previous value: XX. Current value: XX.

From reading about it, its kind of expected due to uni-directional data flow in Angular2. I wonder how to make it work properly in my scenario?

I temporarily injected ChangeDetectorRef in component A and call its detectChanges() method in the function that handles @Output event from instance of C. I am worried that its not very efficient tho. I could probably try improve it and call it only after the last item's event (all the C components send that event at the same time) but then I would be worried about async nature of the events and some unexpected behaviors.

Does anyone have an idea how to overcome this problem? Is my design fundamentally flawed in terms of the data flow between the components? Should I go for something like a shared service instead to exchange data?

Any help much appreciated.

1条回答
贪生不怕死
2楼-- · 2019-02-20 23:34

You can inject private cdRef:ChangeDetectorRef and call this.cdRef.detectChanges() at the end of ngOnChanges(). This way Angular runs change detection again and won't complain about previously modified model values.

class MyComponent {
  constructor(private cdRef:ChangeDetectorRef) {}

  ngOnChanges(changes) {
    this.xxx = ...
    ...
    this.cdRef.detectChanges();
  }
}
查看更多
登录 后发表回答