Service events do not affect template correctly

前提是你 提交于 2019-12-10 15:44:33

问题


Auth in google, use Angular2.

First, in HTML, I load google api library:

//index.html
//...
<script> 
       var googleApiClientReady = function() {
          ng2Gauth.googleApiClientReady(gapi);
      }
    </script>    
    <script src="https://apis.google.com/js/client.js?onload=googleApiClientReady"></script>
//...

After in Angular2 service I handle google auth data and emit event to inform component if google api is ready:

//google auth service .ts
import {Injectable, EventEmitter} from 'angular2/core';

@Injectable()
export class GoogleAuthService {

    isGoogleApiReady: EventEmitter<boolean>;

    constructor() {
        window['ng2Gauth'] = this; //is it correct way?
        this.isGoogleApiReady = new EventEmitter;       
    }
    //it fires from outside of Angular scope
    public googleApiClientReady(gapi){
        this.gapi.auth.init( () => { 
            this.isGapiReady.emit(true);
        })
    };
//...

Here, in the component, I check checkbox, or make buttons disabled, and do other template stuff.

//gauth component
import {Component} from 'angular2/core';
import {GauthService} from './gauth.service';

@Component({
    selector: 'gauth',
    template: `<input type="checkbox" [(ngModel)]="isReady"> Api ready

export class GauthComponent {
    constructor (private _gauthService:GauthService) {
        _gauthService.isGoogleApiReady.subscribe( (flag) =>   this.gapiOnReady(flag) )

  public isReady = false
  gapiOnReady(flag: boolean) { //it fires, 
    this.isReady = true;       //but not affect on template correctly
    console.log('gapi loaded') 
    this._gauthService.checkAuth();     
  }
}

It looks like all should work but there is weird bug in browsers (Chrome, FF) - if page loads on active browser's tab - it looks like nothing happens - checkbox no checks, if I open other tabs in time when browser load page, all is ok.

How to fix it? Is it Angular bug or I do it wrong way?


回答1:


Inject NgZone into a component and initialize the library code with zone.run(), this way the library code uses zones patched async API and Angular knows when change detection runs are necessary

var googleApiClientReady;
constructor(private zone: NgZone) {
} 

public googleApiClientReady(gapi){          
  zone.run(function () { 
    this.gapi.auth.init( () => { 
        this.isGapiReady.emit(true);
    })
  });
}  

and

gapiOnReady(flag: boolean) {
  zone.run(function() {
    this.isReady = true;       //but not affect on template correctly
    console.log('gapi loaded') 
    this._gauthService.checkAuth();   
  });
}


来源:https://stackoverflow.com/questions/34835697/service-events-do-not-affect-template-correctly

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