因为项目上要求统一技术栈,最近在学习angular。在学习到组件与模板/生命周期钩子这节的AfterView 钩子时,看到一个“遵循单向数据流规则”部分。这部分有代码如下:
export class AfterViewComponent implements AfterViewChecked, AfterViewInit {
private prevHero = '';
// Query for a VIEW child of type `ChildViewComponent`
@ViewChild(ChildViewComponent) viewChild: ChildViewComponent;
ngAfterViewInit() {
// viewChild is set after the view has been initialized
this.logIt('AfterViewInit');
this.doSomething();
}
ngAfterViewChecked() {
// viewChild is updated after the view has been checked
if (this.prevHero === this.viewChild.hero) {
this.logIt('AfterViewChecked (no change)');
} else {
this.prevHero = this.viewChild.hero;
this.logIt('AfterViewChecked');
this.doSomething();
}
}
private doSomething() {
let c = this.viewChild.hero.length > 10 ? `That's a long name` : '';
if (c !== this.comment) {
// Wait a tick because the component's view has already been checked
this.logger.tick_then(() => this.comment = c);
}
}
}
并且说道:
“为什么在更新 comment
属性之前,doSomething()
方法要等上一拍(tick)?
Angular 的“单向数据流”规则禁止在一个视图已经被组合好之后再更新视图。 而这两个钩子都是在组件的视图已经被组合好之后触发的。
如果立即更新组件中被绑定的 comment
属性,Angular 就会抛出一个错误(试试!)。LoggerService.tick_then()
方法延迟更新日志一个回合(浏览器 JavaScript 周期回合),这样就够了。”
对于这段解释我不是很明白,尤其是里面的周期回合和单向数据流规则。
于是我搜索了以下,得到了一个angular中对于单向数据流规则的解释。
在Angular中,单向数据流规则是指当数据模型发生变化,Angular发动变更检测,调用DOM ompoent render把数据模型转化为DOM数据结构,应用中的数据只会单向转向成DOM数据结构,不可发生其他改变的方向。
Angular通过模板把数据模型转换成视图。
Angular为什么要遵循单向数据流规则呢?
在AngularJS(angular1)中,数据的流动是双向,稍微复杂的情况下,这种流动会变得不可预测,有可能到导致整个应用陷入“无限震荡”中。
我们希望确保在将数据转换为视图的过程中,不会进一步修改数据。数据从组件类流向代表它们的DOM数据结构,生成这些DOM数据结构的行为本身不会对数据进行进一步修改。但在Angular的变更检测周期中,组件的生命周期钩子会被调用,这意味着我们编写的代码在该过程中被调用,该代码有可能引发数据状态发生改变。
上文提到的AfterView钩子中的ngAfterViewChecked就在曲线上面,在变更检测时会被回调,而上文那段回调中的代码如果不延迟一个回合就会改变数据状态。会导致视图渲染后,数据跟视图状态不一致。
参考:https://www.jianshu.com/p/eb1f26d7511f