一切都按预期工作但我无法让视图更新。
我希望ngOnInit()内的订阅能够在每次数据流进入流时更新视图。
但是,虽然数据在流中传输,但代码 this.user = user 不会更新视图:(
我的组件代码是......
import {Component, OnInit} from '@angular/core';
import {Subject, Observable} from 'rxjs/Rx';
import {AuthService} from '../../../services/auth.service';
import 'rxjs/add/operator/catch';
declare let auth2:any;
@Component({
selector: 'user',
templateUrl: 'build/routes/app/user/user.component.html',
styleUrls: ['build/routes/app/user/user.component.css'],
providers: [AuthService]
})
export class UserComponent implements OnInit {
private userSubject = new Subject<string>();
public user:any;
public userStream:Observable<any> = this.userSubject.asObservable().flatMap((code:any) => {
let restStream = this.authService.signIn(code)
.map((response:any) => {
return JSON.parse(response._body);
}).catch((err:any) => {
return Observable.throw(err);
});
return restStream;
}).publish().refCount();
constructor(public authService:AuthService) {
}
ngOnInit() {
this.userStream.subscribe((user:any) => {
console.log(user); // user is set
this.user = user; // this does not update the view :(
});
}
public googleSignIn() {
auth2.grantOfflineAccess({'redirect_uri': 'postmessage'}).then((authResult:any) => {
this.userSubject.next(authResult.code);
});
}
}
视图很简单......
<button (click)="googleSignIn()">Google Sign In</button>
<div>USER = {{user | json}}</div>
如何让Angular2更新视图?
注意:全局声明auth2指的是全球Google OAuth2 - 谢谢
答案 0 :(得分:1)
通过在订阅中添加另一个控制台日志来确认是否正在设置this.user。
console.log(this.user);
我认为它会被设置,但UI不是更新是你的问题。只是为了入门,您可以尝试在超时中包装用户集,并查看UI更新是否像
setTimeout( user => this.user = user, 0);
如果这让你工作,那么你设置变量太早/太晚,无法进行变化检测。
setTimeout
不是理想的实现方法,所以我们应该以适当的方式重构代码,以确保angular2变化检测能够获得更改。如果这让你工作发布关于模板的更多细节或者提出了一个plunker,我们可以看到什么是更好的实现方式。
答案 1 :(得分:0)
问题见于此解释性代码段..
public googleSignIn() {
this.user = {fred:5}; // BINDINGS UPDATE HERE
auth2.grantOfflineAccess({'redirect_uri': 'postmessage'}).then((authResult:any) => {
this.user = {fred:6}; // BINDINGS DO NOT UPDATE HERE
this.userSubject.next(authResult.code);
});
}
任何尝试更新 auth2.grantOfflineAccess 内的数据或由此产生的任何功能或流都无法更新视图!
我最终使用JavaScript事件解决了这个问题。
这里的主要区别是在 this.userStream.subscribe 内部调度一个事件,并且事件监听器设置 this.user
这是我最后的工作解决方案..
import {Component, OnInit} from '@angular/core';
import {Subject, Observable} from 'rxjs/Rx';
import {AuthService} from '../../../services/auth.service';
import 'rxjs/add/operator/catch';
declare let auth2:any;
@Component({
selector: 'user',
templateUrl: 'build/routes/app/user/user.component.html',
styleUrls: ['build/routes/app/user/user.component.css'],
providers: [AuthService]
})
export class UserComponent implements OnInit {
public user:any;
private userSubject = new Subject<string>();
public userStream:Observable<any> = this.userSubject.asObservable().flatMap((code:any) => {
let restStream = this.authService.signIn(code)
.map((response:any) => {
return JSON.parse(response._body);
}).catch((err:any) => {
return Observable.throw(err);
});
return restStream;
}).publish().refCount();
constructor(public authService:AuthService) {
}
ngOnInit() {
this.addUserEventListener();
this.subscribeToUserStream();
}
public googleSignIn() {
auth2.grantOfflineAccess({'redirect_uri': 'postmessage'}).then((authResult:any) => {
this.userSubject.next(authResult.code);
});
}
private addUserEventListener() {
document.addEventListener('userEvent', (e:CustomEvent) => {
this.user = e.detail;
});
}
private subscribeToUserStream() {
this.userStream.subscribe((user:any) => {
let userEvent = new CustomEvent('userEvent', {'detail': user});
document.dispatchEvent(userEvent);
});
}
}
此解决方案有效,但我不知道为什么 auth2.grantOfflineAccess 会导致Angular2出现此类问题。
值得知道这个在auth2.grantOfflineAccess
内的auth2.grantOfflineAccess === 这个之外