Pat*_*Pat 7 observable angular2-changedetection angular angular-input
我复制了一个简单的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;
}
Run Code Online (Sandbox Code Playgroud)
子组件(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);
}
Run Code Online (Sandbox Code Playgroud)
如果 useHttpGet 为 true 则不起作用,如果为 false 则一切正常。
我意识到可能有不同的方法来执行此操作或手动触发更改检测,但我更感兴趣的是为什么这不起作用,因为这对我来说没有任何意义。
也许了解其实际效果的最佳方法是关注 stackblitz 演示。
如果使用onPush,你应该切换到使用BehaviorSubject,这种情况会发生,因为你的父组件也有onPush,这就是为什么你应该使用Subject或手动调用DetectChanges
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {
constructor(private http: HttpClient) {
}
public isHelloVisibleSubject: BehaviorSubject<boolean> = new BehaviorSubject(false);
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.isHelloVisibleSubject.next(true);
});
} else {
this.isHelloVisibleSubject.next(true);
}
}
closeHello() {
this.isHelloVisibleSubject.next(false);
}
<hello [showHello]="isHelloVisibleSubject | async"> </hello
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12822 次 |
最近记录: |