使用setAdminLogicalUser()
以编程方式将服务类的可观察值设置为新值时,模板值会正确刷新,而不会执行组件类中的观察代码。
我认为不执行观察代码的原因是由于以下简单的事实:将可观察对象设置为新实例,因此任何观察者都将“丢失”而替换了旧实例。但是,为什么模板仍然可以刷新,它在内部是否使用另一种订阅观察者的方式?
服务:
@Injectable()
export class AuthService {
user: Observable<User>;
constructor(
private afAuth: AngularFireAuth,
private afs: AngularFirestore) {
this.user = this.afAuth.authState
.switchMap(user => {
if (user) {
return this.afs.doc<User>(`users/${user.uid}`).valueChanges()
} else {
return Observable.of(null)
}
})
setAdminLogicalUser(uid: string) {
this.user = this.afs.doc<User>(`users/${uid}`).valueChanges()
}
}
组件模板:
<div *ngIf="auth.user | async as user">
<!-- following attributes properly refresh after authService.setAdminLogicalUser() -->
<h1 *ngIf="!auth.isAdmin(user)">{{user.firstName}} {{user.lastName}}</h1>
...
组件类:
export class ProfileComponent {
constructor(
public auth: AuthService
}
ngOnInit() {
this.auth.user.subscribe(userData => {
// not executed after authService.setAdminLogicalUser()
console.log('this.auth.user.subscribe')
})
}
}
答案 0 :(得分:1)
因为Angular使用更改检测,因此在每次更改检测时都会评估模板中的表达式。
因此,它检测到auth.user
已更改,并将新值传递到async
管道。
ngOnInit
中的代码仅执行一次,因此订阅了user
执行时存储在auth
中的ngOnInit
观察值。
不要为可观察对象分配新值,而应从不更改可观察对象,而应该从该可观察对象发出新值(即使用Subject)。