Angular 4中如何检测自定义类型@Input()绑定的变化
在Angular 4中检测自定义类型@Input绑定变化的几种方法
针对你提出的问题,结合你的代码示例,我来给你讲讲Angular 4里怎么检测自定义类型@Input的变化:
首先要明确一个关键点:Angular默认的变更检测是引用对比——只有当@Input的引用发生改变时(比如给它重新赋值一个新对象),才会触发默认的变化检测钩子。如果只是修改现有对象的属性(像你示例里修改emp.Name),默认不会触发ngOnChanges,这点要特别注意。
下面是几种常用的解决方案:
1. 使用ngOnChanges钩子(适用于引用变化的场景)
这是Angular提供的标准变更检测钩子,专门用来监听@Input的变化。你可以在子组件(hello组件)里实现这个钩子:
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { Employee } from './app.models'; @Component({ selector: 'hello', template: `<h1>Hello {{employee.Name}}!</h1>` }) export class HelloComponent implements OnChanges { @Input() employee: Employee; ngOnChanges(changes: SimpleChanges) { // 检查employee这个输入属性的变化 if (changes['employee']) { console.log('Employee对象引用发生变化:', changes['employee'].currentValue); // 在这里写你需要的变化处理逻辑 } } }
注意:如果只是在父组件里修改emp.Name,因为emp的引用没变化,ngOnChanges不会触发。这时候如果你想让它触发,可以在父组件修改属性后,重新生成一个新的Employee对象:
// 在AppComponent里修改Name后 this.emp = { ...this.emp }; // 用扩展运算符创建新对象,改变引用
2. 使用ngDoCheck钩子(适用于对象属性变化的场景)
如果需要监听对象内部属性的变化,ngDoCheck会在每次变更检测周期运行,你可以手动对比对象属性的变化。借助KeyValueDiffers可以更方便地检测对象属性的变更:
import { Component, Input, DoCheck, KeyValueDiffers } from '@angular/core'; import { Employee } from './app.models'; @Component({ selector: 'hello', template: `<h1>Hello {{employee.Name}}!</h1>` }) export class HelloComponent implements DoCheck { @Input() employee: Employee; private differ: any; constructor(private differs: KeyValueDiffers) { // 创建一个差异检测器 this.differ = this.differs.find({}).create(); } ngDoCheck() { const changes = this.differ.diff(this.employee); if (changes) { // 遍历所有变化的属性 changes.forEachChangedItem(item => { console.log(`属性 ${item.key} 从 ${item.previousValue} 变为 ${item.currentValue}`); // 处理属性变化的逻辑写在这里 }); } } }
3. 给@Input设置Setter(灵活监听输入变化)
如果你想在@Input赋值时做一些自定义逻辑,或者把对象的变化转化为可检测的输入,可以给@Input设置setter:
import { Component, Input } from '@angular/core'; import { Employee } from './app.models'; @Component({ selector: 'hello', template: `<h1>Hello {{_employee.Name}}!</h1>` }) export class HelloComponent { private _employee: Employee; @Input() set employee(emp: Employee) { // 这里可以对比新旧值,做自定义处理 console.log('Employee输入更新:', emp); this._employee = emp; } get employee(): Employee { return this._employee; } }
和ngOnChanges一样,这个setter只有在employee的引用变化时才会触发,如果只是修改对象属性,还是需要配合引用变更或者ngDoCheck来处理。
内容的提问来源于stack exchange,提问作者Neeraj Singh
相关产品推荐
相关产品推荐

