用于回调内更新的角度变化检测

时间:2017-09-18 16:51:05

标签: angular typescript

我正在寻找关于一个简单问题的推理。 我有一个简单的组件,它有一个布尔属性,我显示在组件的模板中。现在的问题是,如果我在回调中更新此属性,属性确实会更新(在组件中)但更新的值没有渲染(更改检测不起作用,我必须显式调用changeDetectorRef.detectChanges();来呈现更新的值)。

我的模板中有这个:

<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();
  }

你可以看到预期的行为是:最初&#34; isUserLoggedIn&#34;将是假的,然后用户点击&#34;登录&#34;按钮,从另一个服务调用一个函数并切换&#34; isUserLoggedIn&#34;在该函数的successCallback中,因此导致模板元素也被切换。

但是这只有在我取消注释successCallback()中的第一行时才会发生, 我的任务是为什么我需要明确调用changeDetectorRef.detectChanges()来反映dom中的变化,为什么更改检测不能用于回调(我检查了其他方面,简单的Observable.interval(2000).subscribe(x => {this.isUserLoggedIn = !this.isUserLoggedIn});完全没问题)

1 个答案:

答案 0 :(得分:6)

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

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');

欲了解更多信息,请阅读: