我正在寻找关于一个简单问题的推理。
我有一个简单的组件,它有一个布尔属性,我显示在组件的模板中。现在的问题是,如果我在回调中更新此属性,属性确实会更新(在组件中)但更新的值没有渲染(更改检测不起作用,我必须显式调用changeDetectorRef.detectChanges();
来呈现更新的值)。
我的模板中有这个:
<div *ngIf="isUserLoggedIn">
<router-outlet></router-outlet>
</div>
<div *ngIf="!isUserLoggedIn">
<div id="googleBtn" (click)="onSignIn()">Sign In</div>
</div>
这在我的组件中:
gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: '769107420471-782b0i2f3dt9u05dhrb4j21g7ajglrg6.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin',
scope: 'profile email'
});
var googleBtn = document.getElementById('googleBtn');
if(googleBtn) {
this.attachSignin(document.getElementById('googleBtn'));
}
});
}
public attachSignin(element) {
this.auth2.attachClickHandler(element, {},
(googleUser) => {
this.signUpService.googleLogin(googleUser.getAuthResponse().id_token,
this.successCallback.bind(this),
this.signOut.bind(this));
}, (error) => {
alert(JSON.stringify(error, undefined, 2));
});
}
successCallback = function (data) {
// this.changeDetectorRef.detectChanges();
this.isUserLoggedIn = this.utils.isUserLoggedIn();
}
你可以看到预期的行为是:最初&#34; isUserLoggedIn&#34;将是假的,然后用户点击&#34;登录&#34;按钮,从另一个服务调用一个函数并切换&#34; isUserLoggedIn&#34;在该函数的successCallback中,因此导致模板元素也被切换。
但是这只有在我取消注释successCallback()中的第一行时才会发生,
我的任务是为什么我需要明确调用changeDetectorRef.detectChanges()
来反映dom中的变化,为什么更改检测不能用于回调(我检查了其他方面,简单的Observable.interval(2000).subscribe(x => {this.isUserLoggedIn = !this.isUserLoggedIn});
完全没问题)
答案 0 :(得分:6)
它不起作用,因为load
事件回调是在Angular区域之外触发的。你可以像这样解决它:
constructor(private zone: NgZone) {}
gapi.load('auth2', () => {
zone.run(() => {
this.auth2 = gapi.auth2.init({
client_id: '769107420471-glrg6.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin',
scope: 'profile email'
});
var googleBtn = document.getElementById('googleBtn');
欲了解更多信息,请阅读: