在写本周的实验时又发现了一个之前没有注意到的angular的报错segmentfault
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngForOf: [object Object]'. Current value: 'ngForOf: undefined'.
网上找了找出现这个的缘由,大概就是视图层显示的数据和c层的数据不一致形成的
。dom
视图都成功的渲染出来了,为何还会报错呢?spa
先来了解一下angular的渲染流程3d
Angular 程序实际上是一个组件树,在变动检测期间,Angular 会按照如下顺序检查每个组件(注:这个列表称为列表 1):双向绑定
- 更新全部子组件/指令的绑定属性
- 调用全部子组件/指令的三个生命周期钩子:
ngOnInit
,OnChanges
,ngDoCheck
- 更新当前组件的 DOM
- 为子组件执行变动检测(注:在子组件上重复上面三个步骤,依次递归下去)
- 为全部子组件/指令调用当前组件的
ngAfterViewInit
生命周期钩子在每一次操做后,Angular 会记下执行当前操做所须要的值,并存放在组件视图的
oldValues
属性里(注:Angular Compiler 会把每个组件编译为对应的 view class,即组件视图类)。在全部组件的检查更新操做完成后,Angular 并非立刻接着执行上面列表中的操做,而是会开始下一次digest cycle,即 Angular 会把来自上一次 digest cycle 的值与当前值比较(注:这个列表称为列表 2):code
- 检查已经传给子组件用来更新其属性的值,是否与当前将要传入的值相同
- 检查已经传给当前组件用来更新 DOM 值,是否与当前将要传入的值相同
- 针对每个子组件执行相同的检查(注:就是若是子组件还有子组件,子组件会继续执行上面两步的操做,依次递归下去。)
因此个人代码开始时的渲染是没问题,问题出在后面的变动检测,方向有了,就去找为啥吧。blog
通过排查发现问题是来自这里
众所周知,pop()
是弹出,而angular不是双向绑定的,这就形成视图层的数据发生了改变,而c层的数据没有改变,也就形成了该错误的出现。递归
[译] 关于 `ExpressionChangedAfterItHasBeenCheckedError` 错误你所须要知道的事情生命周期