我正在尝试实施一项服务,该服务将使用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,但我已经怀疑它可能与回调有关,所以我已经尝试更改setTimeout
内setTimeout
内setTimeout
的值ChangeDetectorRef
1}}并且视图已成功更新。
我终于找到了一个解决方案,在设置private detector
的值后,将detector.detectChanges()
注入isLoggedIn
并调用{{1}}。
所以我不是要求一个解决方案,我问的是,如果有人知道为什么会发生这种奇怪的行为,为什么我必须使用变化检测器进行一项操作,至少对我而言,似乎是某种操作这应该由Angular本身处理。或者我错过了什么,这种行为是正常的吗?
答案 0 :(得分:1)
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
});
});
}