是否有一个生命周期钩子在组件初始化后运行一次,但也在加载双向绑定后运行?
Posted
技术标签:
【中文标题】是否有一个生命周期钩子在组件初始化后运行一次,但也在加载双向绑定后运行?【英文标题】:Is there a lifecycle hook that runs once after a components initialisation, but also after two-way-binding is loaded? 【发布时间】:2019-11-04 18:21:16 【问题描述】:我试图在组件初始化后在输入字段中选择一些文本。我知道我可以通过 setTimeout()
做到这一点,但感觉有点太老套了。
大多数钩子在输入文本被双向绑定加载之前运行。每次有人选择其他字段时,其他字段也会运行。
代码:https://stackblitz.com/edit/angular-pxrssq
import Component, OnInit, Input, ViewChild from '@angular/core';
@Component(
selector: 'app-child',
template: `
<input #input type="text" [(ngModel)]="info.one"/>
<input type="text" [(ngModel)]="info.two"/>`,
styleUrls: ['./child.component.css']
)
export class ChildComponent implements OnInit
@Input() info;
@ViewChild('input', static: true ) input;
constructor()
ngOnInit()
this.input.nativeElement.select();
是否有一个生命周期钩子在组件初始化之后运行一次,但在加载双向绑定之后?
【问题讨论】:
@SiddAjmera 不,我试过AfterViewInit
。它应该选择文本,而不是(以便在双向绑定完成之前加载)。 stackblitz.com/edit/angular-hsqvrq
【参考方案1】:
事实上,使用setTimeout()
不是一个hacky 解决方案,它是the 解决方案。因为angular's unidirectional data flow rule。
Angular 的单向数据流规则禁止在视图组合后对其进行更新。
为了观察此规则的后果,请尝试在AfterViewInit
挂钩上为ChildComponent
的info
属性分配一个新值。你会得到一个ExpressionChangedAfterItHasBeenCheckedError
,这是 Angular 的说法,即“禁止在视图组合后更新视图!”
由于您没有更新任何组件的数据绑定属性,只是进行 dom 操作,因此 angular 不会引发任何错误,但也不会反映您对 dom 的更改。
回到你的问题;
是否有一个生命周期钩子在组件初始化之后运行一次,但在加载双向绑定之后?
是的,它是AfterViewInit 钩子。因为;
在调用 ngAfterViewInit 回调之前设置视图查询。
在调用ngAfterViewInit
之前处理DOM 更新,如here 中所述。
它来了afterOnChanges钩子,在哪里;
当指令的任何数据绑定属性发生更改时,将调用 OnChanges。
因此,如果您希望在第一次加载组件时只选择一次文本,则应执行以下操作。
ngAfterViewInit()
setTimeout(() => this.input.nativeElement.select());
如果您想在input
属性被父组件更改时选择文本(包括首次加载),那么您需要实现OnChanges
挂钩。
ngOnChanges()
setTimeout(() => this.input.nativeElement.select());
这是一个工作演示https://stackblitz.com/edit/angular-owahps
希望对你有帮助。
【讨论】:
以上是关于是否有一个生命周期钩子在组件初始化后运行一次,但也在加载双向绑定后运行?的主要内容,如果未能解决你的问题,请参考以下文章