I'm working on an electron application, whose client side is written in Angular2.
I'm having the classic problem that a lot of people have encountered (eg. here and here), namely that I'm updating my component's data, but the view doesn't get updated because Angular doesn't know that the data has changed. The solutions people suggest (see above and also here) is to manually run change detection, either on the whole component tree, or part of it (similar to Angular 1's $rootScope.$digest
and $scope.$digest
).
However, I'd like to avoid wrapping all my data changes in zone.run()
calls, as it slightly defeats the purpose of using Angular.
I'm pretty sure I know why this happens: I'm creating Bluebird Promises outside of Angular, in electron code (ie, the main process), and these aren't Zone aware, so they don't notify Angular of the changes.
I don't know how to solve it, though. What can I do to create Zone aware promises in my electron code, to avoid having to manually run change detection all the time? Can I convert my Bluebird Promises to Zone aware Promises somehow?
EDIT: I think I was wrong, Bluebird promises aren't Zone aware even if created within angular. They're just not Zone aware in general.
EDIT 2: I was completely wrong in the previous edit. Bluebird promises work just fine with zones. However, in the context of an electron application, creating a promise in the main electron process and using it in the renderer process (where Angular lives), doesn't work, as the returned promise isn't zone-aware. Creating the promise from Angular code worked.
Angular runs its change detection mechanism periodically so that changes to the data model are reflected in an application's view. Change detection can be triggered either manually or through an asynchronous event (for example, a user interaction or an XMLHttpRequest completion).
Async pipe does't trigger changeDetection and do not redraw value in UI.
An observable notices a mutation in the object without creating a new reference for it. So, you can subscribe to an observable, and, whenever a change happens, manually run the change detector inside the subscribe method to update the view.
Default change detection strategy is applied to the component while it is created. If a component strategy is not configured, it is marked as default. In this strategy, the change detection cycle runs on each and every event that occur inside the Component.
Promises don't make Angular run change detection with ChangeDetectionStrategy.OnPush
except when you use the async pipe ... | async
.
When code is initialized outside Angular2 it runs outside Angulars zone. What you can do is to move initialization inside your Angular2 code or use ´zone.run(...)to move execution inside Angulars zone. There is nothing bad about
zone.run(...)`.
If the code executed only changes local properties of a component you can use ChangeDetectorRef.detectChanges()
to run change detection for this component.
If the code causes changes in other components (like for example this.router.navigate(...)
, then detectChanges()
is not sufficient. For this case zone.run()
should be used.
setTimeout(...)
triggers change detection for the whole application and should be avoided as a way to invoke change detection manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With