我复制了一个简单的stackblitz 来展示我遇到的问题。问题是我有一个将布尔值传递给子组件的父组件。此布尔值是子组件上的 @Input。需要注意的是,父组件使用 ChangeDetectionStrategy.OnPush。子组件没有明确设置。
当父组件在订阅方法中更改子组件的布尔输入属性时,子组件最初不会检测到更改。总是需要点击 2 次才能让子组件检测到更改。
但是,当我在订阅方法之外更改子组件的布尔输入属性时,正确检测到更改的子组件,并且一切都按预期工作(1 单击子组件以识别更改)。
App.Component.ts(父组件)
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {
constructor(private http: HttpClient) {
}
public isHelloVisible: boolean;
public useHttpGet: boolean;
showHello() {
if (this.useHttpGet) {
this.http.get('https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/cc0e3799790b0b34bdeb6fef28c3daf7/17.447409200000003,-78.3724573?units=si').subscribe(data => {
this.isHelloVisible = true;
});
} else {
this.isHelloVisible = true;
}
}
closeHello() {
this.isHelloVisible = false;
}
子组件 (Hello.component.ts)
@Component({
selector: 'hello',
template: `<div *ngIf="showHello">
Hello
<div (click)="closeHello()">Click me to close Hello</div>
</div>
`,
styles: []
})
export class HelloComponent {
@Input() showHello: boolean;
@Output() close: EventEmitter<any> = new EventEmitter();
ngOnChanges(changes: SimpleChanges): void {
console.log(this.showHello);
}
closeHello() {
this.close.emit(null);
}
如果 useHttpGet 为 true,则它不起作用,如果为 false,则一切正常。
我意识到可能有不同的方法可以做到这一点或手动触发更改检测,但我更感兴趣的是为什么这不起作用,因为这对我没有任何意义。
看到这一点的最佳方式可能是跟随 stackblitz 演示。