是否有一个生命周期钩子在组件初始化后运行一次,但也在加载双向绑定后运行?

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 挂钩上为ChildComponentinfo 属性分配一个新值。你会得到一个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

希望对你有帮助。

【讨论】:

以上是关于是否有一个生命周期钩子在组件初始化后运行一次,但也在加载双向绑定后运行?的主要内容,如果未能解决你的问题,请参考以下文章

初始化所有孩子后的Angular 2生命周期钩子?

自学ng -生命周期钩子

React Native的生命周期解析

Vue——生命周期和钩子函数的一些理解

react 生命周期钩子函数

React组件生命周期