尽管我们在父组件中两次更改 属性 的值,但 ngOnChanges 没有被调用两次
ngOnChanges not getting called twice although we are changing the value of property twice in parent component
有两个组件,即ParentComponent 和ChildComponent。我们正在将变量从父组件绑定到子组件。根据 angular 文档,只要父组件中 属性 的值发生变化,就会调用子组件的 "ngOnChanges"。现在,在 ParentComponent 中,我们两次更改该变量的值,但在 ChildComponent 中, "ngOnChanges" 仅被调用一次。
父组件如下:
ParentComponent.html
<p>parentcomponent works!</p>
<button (click)="onClicking()">Click here</button>
<app-childcomponent [temp]="inputfromparent"></app-childcomponent>
ParentComponent.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-parentcomponent',
templateUrl: './parentcomponent.component.html',
styleUrls: ['./parentcomponent.component.css']
})
export class ParentcomponentComponent implements OnInit {
private inputfromparent = "B"
constructor() { }
ngOnInit() {
}
onClicking(){
this.inputfromparent = "C"; //line1
console.log("Hello");
this.inputfromparent= "D"; //line2
}
}
子组件如下:
ChildComponent.ts
import { Component, OnInit, OnChanges, Input } from '@angular/core';
@Component({
selector: 'app-childcomponent',
templateUrl: './childcomponent.component.html',
styleUrls: ['./childcomponent.component.css']
})
export class ChildcomponentComponent implements OnInit, OnChanges{
@Input() private temp = "A";
constructor() { }
ngOnInit() {
}
ngOnChanges(change){
var test = change;
console.log(test);
console.log(this.temp);
}
}
在 ParentComponent.ts 文件中,每当 "onClicking" 方法在单击 ParentComponent.html 文件中定义的按钮时被调用时,我们将 "inputfromparent " 的值更改两次(参考第 1 行和第 2 行).由于我们将此变量与 ChildComponent.ts 文件的变量 "temp" 绑定,因此 ChildComponent.ts 文件的 "ngOnChanges" 应该根据 angular 文档被调用两次,即如下:
A lifecycle hook that is called when any data-bound property of a directive changes. Define an ngOnChanges() method to handle the changes.
但是 ChildComponent.ts 文件的 "ngOnChanges" 仅在单击 ParentComponent.html 文件中定义的按钮时调用 "onClicking" 一次。
我的疑问是,由于我们正在更改 "inputfromparent" 的值,在 ParentComponent.ts 文件的 "onClicking" 方法中两次,所以 "ngOnChanges" 的 [=50] =] 文件应该被调用两次。但它只被调用一次。
onClicking() {
this.inputfromparent = "C"; //line1
console.log("Hello");
this.inputfromparent= "D"; //line2
}
这 运行 是同步的。也就是说,在 onClicking
结束其 运行 之前不会执行其他代码:对于整个外部世界(模板引擎、变更检测等), onClicking()
在它之前被调用, inputfromparent
的值为 "B",之后为 "D"。两者之间几乎是一个黑盒子。
你应该调用 changedetector 否则你会从 angular 得到异常。请检查控制台。
export class ParentcomponentComponent implements OnInit {
private inputfromparent = "B";
constructor(private cd: ChangeDetectorRef) { }
ngOnInit() {
}
onClicking(){
this.inputfromparent = "C"; //line1
this.cd.detectChanges();
console.log("Hello");
this.inputfromparent= "D"; //line2
this.cd.detectChanges();
}
}
一些想法:
inputfromparent 应该是 public 以避免使用 AOT 进行生产构建
ChildComponent 应该使用 OnPush 更改检测。
有两个组件,即ParentComponent 和ChildComponent。我们正在将变量从父组件绑定到子组件。根据 angular 文档,只要父组件中 属性 的值发生变化,就会调用子组件的 "ngOnChanges"。现在,在 ParentComponent 中,我们两次更改该变量的值,但在 ChildComponent 中, "ngOnChanges" 仅被调用一次。
父组件如下:
ParentComponent.html
<p>parentcomponent works!</p>
<button (click)="onClicking()">Click here</button>
<app-childcomponent [temp]="inputfromparent"></app-childcomponent>
ParentComponent.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-parentcomponent',
templateUrl: './parentcomponent.component.html',
styleUrls: ['./parentcomponent.component.css']
})
export class ParentcomponentComponent implements OnInit {
private inputfromparent = "B"
constructor() { }
ngOnInit() {
}
onClicking(){
this.inputfromparent = "C"; //line1
console.log("Hello");
this.inputfromparent= "D"; //line2
}
}
子组件如下:
ChildComponent.ts
import { Component, OnInit, OnChanges, Input } from '@angular/core';
@Component({
selector: 'app-childcomponent',
templateUrl: './childcomponent.component.html',
styleUrls: ['./childcomponent.component.css']
})
export class ChildcomponentComponent implements OnInit, OnChanges{
@Input() private temp = "A";
constructor() { }
ngOnInit() {
}
ngOnChanges(change){
var test = change;
console.log(test);
console.log(this.temp);
}
}
在 ParentComponent.ts 文件中,每当 "onClicking" 方法在单击 ParentComponent.html 文件中定义的按钮时被调用时,我们将 "inputfromparent " 的值更改两次(参考第 1 行和第 2 行).由于我们将此变量与 ChildComponent.ts 文件的变量 "temp" 绑定,因此 ChildComponent.ts 文件的 "ngOnChanges" 应该根据 angular 文档被调用两次,即如下:
A lifecycle hook that is called when any data-bound property of a directive changes. Define an ngOnChanges() method to handle the changes.
但是 ChildComponent.ts 文件的 "ngOnChanges" 仅在单击 ParentComponent.html 文件中定义的按钮时调用 "onClicking" 一次。
我的疑问是,由于我们正在更改 "inputfromparent" 的值,在 ParentComponent.ts 文件的 "onClicking" 方法中两次,所以 "ngOnChanges" 的 [=50] =] 文件应该被调用两次。但它只被调用一次。
onClicking() {
this.inputfromparent = "C"; //line1
console.log("Hello");
this.inputfromparent= "D"; //line2
}
这 运行 是同步的。也就是说,在 onClicking
结束其 运行 之前不会执行其他代码:对于整个外部世界(模板引擎、变更检测等), onClicking()
在它之前被调用, inputfromparent
的值为 "B",之后为 "D"。两者之间几乎是一个黑盒子。
你应该调用 changedetector 否则你会从 angular 得到异常。请检查控制台。
export class ParentcomponentComponent implements OnInit {
private inputfromparent = "B";
constructor(private cd: ChangeDetectorRef) { }
ngOnInit() {
}
onClicking(){
this.inputfromparent = "C"; //line1
this.cd.detectChanges();
console.log("Hello");
this.inputfromparent= "D"; //line2
this.cd.detectChanges();
}
}
一些想法: inputfromparent 应该是 public 以避免使用 AOT 进行生产构建 ChildComponent 应该使用 OnPush 更改检测。