我有一个login()
函数,在我的模板中,有一个绑定到组件的{{message}}
变量。
这是登录功能:
login() {
this.busy = true;
this.message = 'Trying to log in ...'; // correctly updates the template here
this.authService.login().subscribe(
() => {
this.busy = false;
if(!this.authService.isAuthenticated()) {
return;
}
this.router.navigate(['/']);
},
error => {
console.log(this.message);
console.error(error);
this.busy = false;
this.setErrorMessage();
console.log(this.message);
}
);
}
问题是在“错误”回调中,当我调用this.setErrorMessage()
时,模板没有得到更新。
我在console.log(this)
之后做了this.setErrorMessage()
,并且组件变量确实设置正确,但它没有反映在HTML中。
有什么想法吗?
更新
更新了error
功能。也尝试使用.catch()作为@GünterZöchbauer建议。没有运气。
这是setErrorMessage()
函数:
setErrorMessage() {
this.message = 'There was an error while trying to log you in. Please try again in a few moments!'
}
相关模板部分:
<p id="GB-login-frame-text">
{{message}}
</p>
authService.login()
函数返回Observable
,如下所示:
login():Observable<any> {
return this.http.get(API_URL + "/login", {headers: this.headers()})
.map(this.parseResponse)
.catch(this.handleError);
}
parseResponse
和handleError
函数:
private parseResponse(response:Response):any {
let result = response.json();
return result.data || {};
}
private handleError(error:any) {
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
if(error.status == 401) {
localStorage.removeItem('user');
window.location.href = '/login';
return;
}
return Observable.throw(errMsg);
}
调用error
函数时控制台输出:
Trying to log in ...
login.component.ts:39 Object {error: "A generic error occurred"}(anonymous function) @ login.component.ts:39SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.error @ Subscriber.ts:204Subscriber._error @ Subscriber.ts:137Subscriber.error @ Subscriber.ts:107(anonymous function) @ auth.service.ts:50SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93onLoad @ http.umd.js:1104ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
login.component.ts:42 There was an error while trying to log you in. Please try again in a few moments!
message
部分正在js
部分中正确更新,但它并未反映在html
中。
答案 0 :(得分:2)
我认为您需要使用catch()
来确保在发生错误后正确执行代码,否则当发生异常时,更改检测将不会在组件上运行:
login() {
this.busy = true;
this.message = 'Trying to log in ...'; // correctly updates the template here
this.authService.login()
.catch( // needs import
error => {
console.error(error);
this.busy = false;
this.setErrorMessage();
return Observable.of([]); // needs import
}
})
.subscribe(
() => {
this.busy = false;
if(!this.authService.isAuthenticated()) {
return;
}
this.router.navigate(['/']);
}
);
}
答案 1 :(得分:2)
基于对问题的评论以及在其他答案中,问题似乎是错误的变化检测不起作用,如果它不在Angular2的NgZone
中运行,则大多数情况下都是如此。我认为这是一个错误,但它是可能的。
您可以使用如下包装:
constructor(private zone:NgZone) {
// ...
}
login() {
this.busy = true;
this.message = 'Trying to log in ...'; // correctly updates the template here
this.authService.login().subscribe(
() => {
this.busy = false;
if(!this.authService.isAuthenticated()) {
return;
}
this.router.navigate(['/']);
},
error => this.zone.run(() => {
console.log(this.message);
console.error(error);
this.busy = false;
this.setErrorMessage();
console.log(this.message);
})
);
}