Reputation: 191779
I am using the angular2-progressbar library to display some circular progress bars in my app. I have a list of inventory items and a service that updates the inventory list. Each inventory item component gets the updated inventory value from a key in the inventory list like so:
export class InventoryComponent implements OnInit {
@ViewChild(CircleProgressComponent): circleComp: CircleProgressComponent;
@Input() deviceKey: string;
private circleOptions: ShapeOptions { /* from angular2-progressbar example */ }
constructor(private inventoryService: InventoryService) { }
ngOnInit(): void {
this.deviceList = this.inventoryService.deviceList;
setInterval(() => {
// this value will be 0 or 1
this.circleComp.animate(this.deviceList[this.deviceKey]);
}, 2000);
}
}
While this does work, it seems very hacky to me to have the interval check only after every 2 seconds when the actual value in the template itself gets updated immediately whenever inventoryService
updates its device list.
I tried implementing OnChange
, but there are two problems:
change
fires before the view init lifecycle, i.e. before circleComp
is available. This breaks things.this.deviceList
is an object and its properties get updated internally, OnChange
does not get fired anyway. Instead I can do an additional check using ngDoCheck
-- this does work, but it is a lot more verbose and #1 still causes a problem.Is there any way to start performing checks after the view has loaded?
Upvotes: 0
Views: 620
Reputation: 209052
Is there any way to start performing checks after the view has loaded?
Use the AfterViewInit
lifecycle hook (override ngAfterViewInit
). This is when the @ViewChild
is available
I think there may be a better solution than polling deviceList
. You could use a Subject
in the service. This will act like an observer and observable, so you can subscribe to it on one end, and publish on the other. For example
import { BehaviorSubject } from 'rxjs/BehaviorSubject'
class InventoryService {
private _inventoryList = new BahaviorSubject<any>({ initialize with data })
inventoryList$ = this._inventoryList.asObservable();
set inventoryList(list: any) {
this._inventoryList.next(list);
}
}
Now you can just subscribe to the list. And whenever you want to update it, just use the setter, and all the subscribers will get the updated list. No need to poll.
Subscriber
service.inventoryList$.subscribe(list => {})
Publisher
service.inventoryList = newList
See also:
Upvotes: 2