角度变化检测以在回调中进行更新 [英] angular change detection for updates within a callback

查看:78
本文介绍了角度变化检测以在回调中进行更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找有关一个简单问题的理由. 我有一个简单的组件,该组件具有一个布尔属性,该属性显示在组件模板中. (更改检测不起作用,我必须显式调用changeDetectorRef.detectChanges();来呈现更新的值).

I am looking for reasoning about a simple problem. I have a simple component which has a boolean property which i display in the component's template.Now the problem is that if I update this property in a callback, the property does get updated (in the component) but the updated value does not get rendered (change detection does not work, and I have to explicitly call changeDetectorRef.detectChanges(); to render the updated value).

我的模板中有这个

<div *ngIf="isUserLoggedIn">
      <router-outlet></router-outlet>
</div>
<div *ngIf="!isUserLoggedIn">
    <div id="googleBtn" (click)="onSignIn()">Sign In</div>
</div>

,这在我的组件中:

gapi.load('auth2', () => {
      this.auth2 = gapi.auth2.init({
        client_id: '769107420471-782b0i2f3dt9u05dhrb4j21g7ajglrg6.apps.googleusercontent.com',
        cookiepolicy: 'single_host_origin',
        scope: 'profile email'
      });
      var googleBtn = document.getElementById('googleBtn');
      if(googleBtn) {
        this.attachSignin(document.getElementById('googleBtn'));
      }
    });
  }
  public attachSignin(element) {
    this.auth2.attachClickHandler(element, {},
      (googleUser) => {
        this.signUpService.googleLogin(googleUser.getAuthResponse().id_token, 
        this.successCallback.bind(this), 
        this.signOut.bind(this));
      }, (error) => {
        alert(JSON.stringify(error, undefined, 2));
      });
  }

  successCallback = function (data) {
    // this.changeDetectorRef.detectChanges();
    this.isUserLoggedIn = this.utils.isUserLoggedIn();
  }

如您所见,预期的行为是:最初,"isUserLoggedIn"为假,然后用户单击登录"按钮,该按钮从另一个服务调用一个函数,并在该函数的successCallback中切换"isUserLoggedIn"导致模板元素也被切换.

as you can see the expected behaviour is : initially "isUserLoggedIn" will be false, and then user clicks on "Sign In" button, which calls a function from another service and toggles "isUserLoggedIn" in the successCallback of that function thus resulting in the template elements also getting toggled.

但这仅在我取消注释successCallback()的第一行时才会发生, 我的追求是为什么我需要显式调用changeDetectorRef.detectChanges()来反映dom中的更改,为什么更改检测不能与回调一起使用(我以其他方式进行了检查,使用简单的Observable.interval(2000).subscribe(x => {this.isUserLoggedIn = !this.isUserLoggedIn});效果很好)

But this only happens if I uncomment the first line in successCallback (), my quest is why do I need to explicitly call changeDetectorRef.detectChanges() to reflect changes in dom, why change detection is not working with callback (I checked other wise, with simple Observable.interval(2000).subscribe(x => {this.isUserLoggedIn = !this.isUserLoggedIn}); which works perfectly fine)

推荐答案

它不起作用,因为load事件回调是在Angular区域之外触发的.您可以这样解决它:

It doesn't work because load event callback is triggered outside of Angular zone. You can fix it like this:

constructor(private zone: NgZone) {}

gapi.load('auth2', () => {
    zone.run(() => {
        this.auth2 = gapi.auth2.init({
            client_id: '769107420471-glrg6.apps.googleusercontent.com',
            cookiepolicy: 'single_host_origin',
            scope: 'profile email'
        });
        var googleBtn = document.getElementById('googleBtn');

有关更多信息,请阅读:

For more information read:

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆