在Google API回调中更改后查看未更新

时间:2016-11-28 09:43:03

标签: angular typescript google-api google-sheets-api

我正在尝试实施一项服务,该服务将使用Google API将用户登录并授权Sheets 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,按钮应消失 - 如果立即授权失败,则该按钮应该可见,以便用户可以手动触发授权。

我面临的问题是,当立即授权成功并且“用户登录,真实”打印在控制台窗口中时,按钮保持可见。 *ngIf绑定不起作用。 isLoggedIn中的更改未得到反映。我找到了类似的帖子here in SO,但我已经怀疑它可能与回调有关,所以我已经尝试更改setTimeoutsetTimeoutsetTimeout的值ChangeDetectorRef 1}}并且视图已成功更新。

我终于找到了一个解决方案,在设置private detector的值后,将detector.detectChanges()注入isLoggedIn并调用{{1}}。

所以我不是要求一个解决方案,我问的是,如果有人知道为什么会发生这种奇怪的行为,为什么我必须使用变化检测器进行一项操作,至少对我而言,似乎是某种操作这应该由Angular本身处理。或者我错过了什么,这种行为是正常的吗?

1 个答案:

答案 0 :(得分:1)

Zone.js不包含

gapi。您需要明确调用更改检测:

constructor(private cdRef:ChangeDetectorRef){
    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);
            }
            cdRef.detectChanges(); // <<<< added
        });
    });
}