我試圖從Angular 2服務中加載腳本https://apis.google.com/js/api.js?onload=initGapi
以調用Google API,但每當我嘗試返回值時腳本完成加載和初始化,async
管道不想將值呈現給模板。當從Google API加載auth2時,更改檢測不會運行
我使用的EventEmitter
在gapi.load()
和gapi.client.init
完成時觸發,並且observable在組件中訂閱。異步管道似乎不想讀取值,直到我單擊相同組件內的按鈕(並可能觸發更改檢測)。當我使用ApplicationRef
的tick()
時,在組件內強制更改檢測不起作用。
與加載的谷歌API的服務如下:
谷歌,api.service.ts
import { Injectable, EventEmitter } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { User, Client } from '../../+home/models';
declare var gapi: any;
@Injectable()
export class GoogleApiService {
CLIENT_ID: string = '....apps.googleusercontent.com';
DISCOVERY_DOCS: string[] = ["https://www.googleapis.com/discovery/v1/apis/admin/directory_v1/rest"];
SCOPES = 'https://www.googleapis.com/auth/admin.directory.user.readonly';
authEmitter: EventEmitter<boolean> = new EventEmitter();
constructor() {
window['initGapi'] = (ev) => {
this.handleClientLoad();
};
this.loadScript();
}
loadScript() {
let script = document.createElement('script');
script.src = 'https://apis.google.com/js/api.js?onload=initGapi';
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);
}
handleClientLoad() {
gapi.load('client:auth2', this.initClient.bind(this));
}
initClient() {
gapi.client.init({
discoveryDocs: this.DISCOVERY_DOCS,
clientId: this.CLIENT_ID,
scope: this.SCOPES
}).then(() => {
this.authEmitter.emit(true);
});
}
get gapi(): Observable<any> {
return this.authEmitter.map(() => 'hello world');
}
}
和組件從服務
app.component閱讀.ts
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { GoogleApiService } from '../../+core/services';
@Component({
template: `
What does the service say?
{{ api$ | async }}
<button (click)="click()">Button</button>`
})
export class InviteEmployeesContainer implements OnInit {
api$: Observable<string>;
constructor(private gApiService: GoogleApiService) {}
ngOnInit() {
this.api$ = this.gApiService.gapi;
this.gApiService.gapi.subscribe((result) => {
console.log(result);
});
}
click() {
console.log('clicked');
}
}
生成的頁面打印出字符串What does the service say?
,並且有一個按鈕,但不會打印文本hello world
,直到我點擊按鈕,這不是所需的行爲,它應該立即顯示在頁面上。
此外,當我訂閱並使用this.gApiService.gapi.subscribe
登錄到控制檯時,它會記錄hello world
,當我期望它。
是否有人知道如何在authEmitter
觸發事件時使用異步管道將hello world
打印到頁面。
你嘗試直接返回它作爲一個getter'獲得API $(){回報this.service.gapi}'。您也可以嘗試使用ChangeDetectorRef來強制更改檢測。 – cyrix
直接返回它並不好,因爲我不希望組件在它準備好之前使用它,它需要執行2個網絡請求並在可以使用之前運行'init',因此我使用了observable。我會嘗試強制更改檢測,但我不認爲這是一個實際的長期解決方案,因爲這通常是我期望可觀察到的事情來處理沒有問題。 – Adam
您知道在準備就緒之前您可以使用'async'管道進行輸入,並且組件一旦發出數據就會立即開始使用它。 (因爲我看到你只是在它加載後才發出新的項目) – cyrix