【问题标题】:Service events do not affect template correctly服务事件不会正确影响模板
【发布时间】:2016-01-17 06:16:12
【问题描述】:

在 google 中验证,使用 Angular2。

首先,在 HTML 中,我加载 google api 库:

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

在 Angular2 服务之后,我处理 google auth 数据并发出事件以通知组件是否 google api 已准备好:

//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);
        })
    };
//...

在这里,在组件中,我选中复选框,或禁用按钮,并执行其他模板操作。

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

看起来一切都应该工作,但浏览器(Chrome,FF)中存在奇怪的错误 - 如果页面在活动浏览器的选项卡上加载 - 看起来没有任何反应 - 复选框不检查,如果我在浏览器加载时及时打开其他选项卡页面,一切正常。

如何解决?是 Angular 错误还是我做错了?

【问题讨论】:

    标签: angular angular2-template angular2-services


    【解决方案1】:

    NgZone 注入组件并使用zone.run() 初始化库代码,这样库代码使用区域修补异步API,Angular 知道何时需要运行更改检测

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

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

    【讨论】:

    • 一样,没用,
    • 谢谢,gapi.auth.init 它可以工作,但是有 gapi.auth.authorize。它在回调中返回身份验证结果,并且在该回调中我需要发出事件。在这里我仍然有同样的问题。
    • 我需要查看代码。我自己不使用这个库。
    猜你喜欢
    • 2017-05-16
    • 2021-04-06
    • 2013-02-21
    • 2011-11-01
    • 2019-06-14
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多