Google APIを使用してユーザーをログインさせ、Sheets APIを承認するサービスを実装しようとしています。そのサービスの簡略化されたバージョン:Google APIコールバックの変更後に更新が反映されないビュー
import {Injectable} from '@angular/core';
declare var gapi;
@Injectable()
export class MyService{
isLoggedIn: boolean = false;
clientId: string = "*******.apps.googleusercontent.com";
scopes: string[] = ["https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/drive"];
constructor(){
gapi.load('client',() => {
console.log("Client Loaded");
gapi.auth.authorize({
client_id: this.clientId,
scope: this.scopes.join(' '),
immediate: true
}, (authResponse) => {
if(authResponse && !authResponse.error){
this.isLoggedIn = true;
console.log("User logged in, " + this.isLoggedIn);
}
else{
this.isLoggedIn = false;
console.log("User not logged in");
console.log(this.isLoggedIn);
}
});
});
}
}
私はprivate myService: MyService
として私AppComponentにそのサービスを注入しています。私のapp.component.html
では、私は、ユーザーがAPIを承認していない場合に表示されている必要があり、簡単なボタンがあります。
<button *ngIf="!myService.isLoggedIn">Authorize</button>
それでは、私がしたいことは次のとおりです。 - サービスはgapi.auth.authorize
を呼び出す - ユーザーが許可している場合APIの場合isLoggedIn
はtrue
に設定され、ボタンは消えます。 - 即時認証が失敗した場合は、ユーザーが手動で認証を開始できるようにボタンが表示されている必要があります。
直面している問題は、直ちに承認が成功し、「ユーザーがログインしたとき、true」がコンソールウィンドウに表示され、ボタンが表示されたままになるという問題です。 *ngIf
バインドが機能しません。 isLoggedIn
の変更は反映されません。私は同様のポストhere in SOを見つけましたが、私は既にそれがコールバックと関係があるかもしれないと疑っていましたので、setTimeout
からsetTimeout
内の値を別のsetTimeout
に変更しようとしました。
最後にChangeDetectorRef
をprivate detector
として注入し、isLoggedIn
の値を設定した後にdetector.detectChanges()
を呼び出して解決策を見つけました。
私は解決策を求めているわけではありません。なぜこの奇妙な動作が起こるのか誰かが知っているのですが、なぜ少なくとも私にとっては変化検出器を使用する必要があるのでしょうか? Angular自身が扱うべきもの。それとも、私は何かを逃していますが、この動作は正常ですか?
これはまさに私がやったことであり、それはうまくいきました。だから、これはZoneの仕組みと関係がありますか? – dimlucas
NgZoneは非同期APIコールを認識していないため、Angular外のgapiを初期化するためだと思います。また、Angular内で初期化して、ゾーンに気づかずにイベントを処理することも可能です。 NgZoneはすべての可能性の100%をカバーしていません。 –