may be I am misunderstanding the changeDetection strategy in angular.
Here is Description:
onPush
change detection strategy. loading
text while http service call is in progress and then removing the text after complete using ngIf
using primitive variable this.loading=true/false
Now My problem is when App loads initially I can see loading...
text on S2 widget and then data gets populated.
But when I click on the notify sibling
button in S1, it does triggers the service call but while http is in process I can't see loading...
text.
Here is code of S1 :
import { Component, OnInit } from '@angular/core';
import { MessagingService } from '../messaging.service';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
constructor(private _sendMessage: MessagingService) { }
ngOnInit() {
}
notifyChild() {
this._sendMessage.notifySibling();
}
}
Here code of S2 :
import { Component, OnInit,ChangeDetectionStrategy ,ChangeDetectorRef} from '@angular/core';
import { MessagingService } from '../messaging.service';
import { switchMap, takeUntil, delay } from 'rxjs/operators';
import { of } from 'rxjs';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent implements OnInit {
public loading = true;
public myData: any;
constructor(private _receiveMessage: MessagingService,private cd: ChangeDetectorRef) { }
ngOnInit() {
this._receiveMessage.registerNotification().pipe(
switchMap(res => {
this.loading = true;
/** Simulate http call below */
return of([res.data]).pipe(
delay(5000)
)
})
).subscribe(response => {
this.myData = response;
this.loading = false;
this.cd.markForCheck();
})
}
}
Note: I have added this.cd.markForCheck();
in subscription. If i comment this like I am only seeing loading...
and no data being displayed
Messaging Service :
import { Injectable } from '@angular/core';
import { Subject, BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class MessagingService {
public _notify = new BehaviorSubject({ data: "initial Call" });
public notify = this._notify.asObservable();
constructor() { }
notifySibling() {
this._notify.next({ data: 'call from sibling' });
}
registerNotification() {
return this.notify;
}
}
Full working example is published on stackblitz
OnPush
strategy run check only when @Input
property is changed if you want to run it in async context you have to call this.cd.markForCheck()
yourself before request and after request.
ngOnInit() {
this._receiveMessage.registerNotification().pipe(
switchMap(res => {
this.loading = true;
/** note this */
this.cd.markForCheck();
return of([res.data]).pipe(
delay(1000)
)
})
).subscribe(response => {
this.myData = response;
this.loading = false;
this.cd.markForCheck();
})
}
https://stackblitz.com/edit/angular-pmvmgz
english ain't my native language :(
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.