为什么在这种情况下 ngOnChanges 不是 运行? (Angular 文档示例)
Why ngOnChanges is not running in this case? (Angular Docs Example)
我正在学习 angular 并且我 运行 从 Angular 文档中学习这个 ngOnChanges 示例 (stackblitz) :
on-changes-parent.component.html
<h2>{{title}}</h2>
<label for="power-input">Power: </label>
<input type="text" id="power-input" [(ngModel)]="power">
<label for="hero-name"> Hero.name: </label>
<input type="text" id="hero-name" [(ngModel)]="hero.name">
<button type="button" (click)="reset()">Reset Log</button>
<on-changes [hero]="hero" [power]="power"></on-changes>
on-changes-parent.component.html
export class OnChangesParentComponent {
hero!: Hero;
power = '';
title = 'OnChanges';
@ViewChild(OnChangesComponent) childView!: OnChangesComponent;
constructor() {
this.reset();
}
reset() {
// new Hero object every time; triggers onChanges
this.hero = new Hero('Windstorm');
// setting power only triggers onChanges if this value is different
this.power = 'sing';
if (this.childView) {
this.childView.reset();
}
}
}
on-changes.component.ts
@Component({
selector: 'on-changes',
template: `
<div class="info">
<p>{{hero.name}} can {{power}}</p>
<h3>Change Log</h3>
<div *ngFor="let chg of changeLog" class="log">{{chg}}</div>
</div>
`
})
export class OnChangesComponent implements OnChanges {
@Input() hero!: Hero;
@Input() power = '';
changeLog: string[] = [];
ngOnChanges(changes: SimpleChanges) {
for (const propName in changes) {
console.log(propName)
const chng = changes[propName];
const cur = JSON.stringify(chng.currentValue);
const prev = JSON.stringify(chng.previousValue);
this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
}
}
reset() { this.changeLog = []; }
}
将 console.log
添加到 ngOnChanges
后,我注意到当我更新 Power
输入时它是 运行ning,但是,当我更新时它不是 运行ning更新 Hero.name
。在这两种情况下,我都希望 ngOnChanges 为 运行。我错过了什么?非常感谢您的解释。
它不会触发,因为它仍然是您引用的同一个英雄,只是名称不同。由于 Angular 使用 ===
检查更改,因此它决定对象没有更改。
解决这个问题的方法是在每次名称更改时创建一个新的英雄对象,或者实现 ngDoCheck
接口来实现您的自定义更改检测。
我正在学习 angular 并且我 运行 从 Angular 文档中学习这个 ngOnChanges 示例 (stackblitz) :
on-changes-parent.component.html
<h2>{{title}}</h2>
<label for="power-input">Power: </label>
<input type="text" id="power-input" [(ngModel)]="power">
<label for="hero-name"> Hero.name: </label>
<input type="text" id="hero-name" [(ngModel)]="hero.name">
<button type="button" (click)="reset()">Reset Log</button>
<on-changes [hero]="hero" [power]="power"></on-changes>
on-changes-parent.component.html
export class OnChangesParentComponent {
hero!: Hero;
power = '';
title = 'OnChanges';
@ViewChild(OnChangesComponent) childView!: OnChangesComponent;
constructor() {
this.reset();
}
reset() {
// new Hero object every time; triggers onChanges
this.hero = new Hero('Windstorm');
// setting power only triggers onChanges if this value is different
this.power = 'sing';
if (this.childView) {
this.childView.reset();
}
}
}
on-changes.component.ts
@Component({
selector: 'on-changes',
template: `
<div class="info">
<p>{{hero.name}} can {{power}}</p>
<h3>Change Log</h3>
<div *ngFor="let chg of changeLog" class="log">{{chg}}</div>
</div>
`
})
export class OnChangesComponent implements OnChanges {
@Input() hero!: Hero;
@Input() power = '';
changeLog: string[] = [];
ngOnChanges(changes: SimpleChanges) {
for (const propName in changes) {
console.log(propName)
const chng = changes[propName];
const cur = JSON.stringify(chng.currentValue);
const prev = JSON.stringify(chng.previousValue);
this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
}
}
reset() { this.changeLog = []; }
}
将 console.log
添加到 ngOnChanges
后,我注意到当我更新 Power
输入时它是 运行ning,但是,当我更新时它不是 运行ning更新 Hero.name
。在这两种情况下,我都希望 ngOnChanges 为 运行。我错过了什么?非常感谢您的解释。
它不会触发,因为它仍然是您引用的同一个英雄,只是名称不同。由于 Angular 使用 ===
检查更改,因此它决定对象没有更改。
解决这个问题的方法是在每次名称更改时创建一个新的英雄对象,或者实现 ngDoCheck
接口来实现您的自定义更改检测。