Angular组件ngOnChanges钩子完全不触发的原因与解决办法
问题原因
Angular 的 ngOnChanges 生命周期钩子仅会在 @Input 修饰的属性由父组件通过模板绑定传入、且父组件侧传入的值发生变更时触发,不符合该条件的@Input属性修改都不会触发钩子:
- 你当前使用的是根组件
AppComponent,不存在上层父组件给它的mydata属性做绑定传值 - 你是在当前组件内部自行修改
mydata的值,不是父组件传入的变更,自然满足不了ngOnChanges的触发条件
修复方案
方案1:拆分父子组件测试ngOnChanges(符合钩子设计初衷)
如果你的核心需求是验证ngOnChanges的触发逻辑,按照Angular的组件设计规范拆分父子组件即可:
- 新增子组件
child.component.ts
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; @Component({ selector: 'app-child', template: `<p>子组件接收值:{{ mydata | json }}</p>` }) export class ChildComponent implements OnChanges { @Input() mydata?: string; ngOnChanges(changes: SimpleChanges) { console.log(changes); // 父组件传值变更时会正常打印 } }
- 修改根组件
app.component.ts,移除不需要的@Input和ngOnChanges逻辑
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { mydata?: string; change() { this.mydata = 'some change here'; } }
- 修改根组件模板
app.component.html,引入子组件并绑定属性
<h1>NG Changes</h1> Changes: {{ mydata | json }} <button (click)="change()">Change</button> <app-child [mydata]="mydata"></app-child>
方案2:不拆组件的情况下监听属性变化
如果你不需要测试ngOnChanges,只是要监听当前组件属性的变更,可以直接用setter拦截属性赋值,不需要依赖ngOnChanges:
import { Component, Input } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { private _mydata?: string; @Input() get mydata(): string | undefined { return this._mydata; } set mydata(val: string | undefined) { this._mydata = val; // 此处写原来要在ngOnChanges中执行的逻辑即可 console.log('mydata 变更为:', val); } change() { this.mydata = 'some change here'; } }
内容的提问来源于stack exchange,提问作者deszok
相关产品推荐
相关产品推荐

