角度变化检测以在回调中进行更新 [英] angular change detection for updates within a callback
问题描述
我正在寻找有关一个简单问题的理由.
我有一个简单的组件,该组件具有一个布尔属性,该属性显示在组件模板中. (更改检测不起作用,我必须显式调用changeDetectorRef.detectChanges();
来呈现更新的值).
I am looking for reasoning about a simple problem.
I have a simple component which has a boolean property which i display in the component's template.Now the problem is that if I update this property in a callback, the property does get updated (in the component) but the updated value does not get rendered (change detection does not work, and I have to explicitly call changeDetectorRef.detectChanges();
to render the updated value).
我的模板中有这个
<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();
}
如您所见,预期的行为是:最初,"isUserLoggedIn"为假,然后用户单击登录"按钮,该按钮从另一个服务调用一个函数,并在该函数的successCallback中切换"isUserLoggedIn"导致模板元素也被切换.
as you can see the expected behaviour is : initially "isUserLoggedIn" will be false, and then user clicks on "Sign In" button, which calls a function from another service and toggles "isUserLoggedIn" in the successCallback of that function thus resulting in the template elements also getting toggled.
但这仅在我取消注释successCallback()的第一行时才会发生,
我的追求是为什么我需要显式调用changeDetectorRef.detectChanges()
来反映dom中的更改,为什么更改检测不能与回调一起使用(我以其他方式进行了检查,使用简单的Observable.interval(2000).subscribe(x => {this.isUserLoggedIn = !this.isUserLoggedIn});
效果很好)
But this only happens if I uncomment the first line in successCallback (),
my quest is why do I need to explicitly call changeDetectorRef.detectChanges()
to reflect changes in dom, why change detection is not working with callback (I checked other wise, with simple Observable.interval(2000).subscribe(x => {this.isUserLoggedIn = !this.isUserLoggedIn});
which works perfectly fine)
推荐答案
它不起作用,因为load
事件回调是在Angular区域之外触发的.您可以这样解决它:
It doesn't work because load
event callback is triggered outside of Angular zone. You can fix it like this:
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');
有关更多信息,请阅读:
For more information read: