How to trigger change detection in Angular2? [duplicate]

天涯浪子 提交于 2019-11-28 19:38:15
Mark Rajcok

Am I doing something wrong? Is there a better way than having to call ApplicationRef.tick() after a change triggered from an external library?

It depends. If you're calling the Facebook APIs outside of Angular (i.e., registering asynchronous event handlers outside Angular), then you'll need to manually run change detection as part of handling any events. You can either

  • inject NgZone and then call run() on that object, which will execute the passed (callback) function inside the Angular zone and then automatically call ApplicationRef().tick(), which will run change detection for the entire app, or
  • inject ApplicationRef and call tick() yourself, or
  • inject ChangeDetectorRef and call detectChanges() yourself -- this will only run change detection on the one component and its children

Note, if you inject NgZone, you don't want to use runOutsideAngular(). That will execute the passed (callback) function outside the Angular zone, and it will not call ApplicationRef().tick(), so change detection will not execute.

If you call the Facebook APIs inside Angular, you might be able to avoid all of the above, because then Angular (via its use of Zone.js) should monkey-patch the asynchronous event calls. Then, when your events fire, ApplicationRef.tick() will automatically be called. See https://stackoverflow.com/a/34593821/215945 for more discussion on this approach.

I'm not sure if it's better. There a couple of other ways I can think of.

Using NgZone

You can inject NgZone and execute the run method with a callback:

 NgZone.run(()=>this.currentUser.next(user));

Using setTimeout

setTimeout will trigger change detection automatically:

setTimeout(()=>this.currentUser.next(user));
Thierry Templier

Could you give us the way you initialize the Facebook provider and you your service in your component?

Option #1

Your behavior makes me change that the Facebook code is running outside an Angular zone, so Angular change detection doesn't run when an event fires. You

You could also run manually the change detection:

import { Component, ChangeDetectorRef } from 'angular2/core';

@Component({
  (...)
})
export class MyComponent {
  constructor(private cdr:ChangeDetectorRef) {
  }

  someMethod() {
    this.cdr.detectChanges();
  }
}

See these questions:

Option #2

Perhaps you event is fired before the component register a callback on the currentUser subject. In this case, you could trigger the event later...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!