angular - Google API 回调更改后 View 未更新

标签 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 注入(inject)到我的 AppComponent 中.在我的 app.component.html我有一个简单的按钮,如果用户没有授权 API,它应该是可见的:

<button *ngIf="!myService.isLoggedIn">Authorize</button>

所以我想要的是: - 服务电话gapi.auth.authorize - 如果用户已授权 API,则 isLoggedIn应设置为 true并且按钮应该消失 - 如果立即授权失败,该按钮应该可见,以便用户可以手动触发授权。

我面临的问题是,当立即授权成功并且控制台窗口中打印“用户已登录,为真”时,该按钮仍然可见。 *ngIf绑定(bind)不起作用。 isLoggedIn 的变化没有体现。我找到了类似的帖子 here in SO但我已经怀疑它可能与回调有关,所以我已经尝试更改 setTimeout 的值在 setTimeout 内在另一个setTimeout并且 View 成功更新。

我终于通过注入(inject) ChangeDetectorRef 找到了解决方案作为private detector并调用 detector.detectChanges()isLoggedIn 设置值后.

所以我不是在寻求解决方案,我想问的是是否有人知道为什么会发生这种奇怪的行为,以及为什么我必须使用变化检测器来进行至少对我来说看起来像是某种操作这应该由 Angular 自己处理。还是我遗漏了什么而这种行为是正常的?

最佳答案

gapi 不在 Zone.js 范围内。您需要显式调用更改检测:

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

关于angular - Google API 回调更改后 View 未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40841197/

相关文章:

hadoop - 谷歌大查询 : Incompatible table partitioning specification

node.js - 从 Gmail API 获取电子邮件的直接 URL(列出消息)

json - 将 JSON 发送到 Web 服务时如何忽略 TypeScript 中的实体字段?

angular - ionic 4 tabbar - 如何始终显示标签根而不是标签子页面

angular - Angular 服务注入(inject)和导入对象字面量的区别

angular - 在 Angular 2+ 中压缩传出请求

javascript - 谷歌饼图 : How can I put the tooltip in front of my central div

Angular 2 单元测试 beforeEachProvider 不注入(inject)服务

angular - 如何在 Angular 中订阅服务

typescript 使用装饰器获取参数的值