【发布时间】:2016-06-01 21:28:20
【问题描述】:
我正在创建一个调用 Facebook javascript api 的 Facebook 服务,并且想知道如何在我的值更新时最好地实现更改检测。
我有一个 UserService,它有一个 currentUser 属性,它是一个 BehaviorSubject:
currentUser: Subject<User> = new BehaviorSubject<User>(new User(null));
当我想更新用户以响应 facebook javascript sdk 告诉我用户已登录或注销时,我会更新该用户并需要在 ApplicationRef 上调用 tick():
updateUser(user: User) {
console.log('UserService.updateUser:', user);
this.currentUser.next(user);
this.appRef.tick(); // UI does not update without this
}
constructor(facebook: Facebook) {
this.facebook.facebookEvents.filter(x => x != null
&& x.eventName == 'auth.authResponseChange')
.subscribe((event) => {
this.updateUser(new User(event.data));
}
}
在我的组件中,我将来自用户服务的“currentUser”存储在构造函数中并绑定到 value 属性:
<h2>Logged into Facebook as {{currentUser.value.name}}</h2>
<p>Is this you? <img src="{{currentUser.value.profilePicUrl}}"></p>
我做错了吗?有没有比在外部库触发更改后必须调用 ApplicationRef.tick() 更好的方法?
编辑
我尝试使用 NgZone,但它不起作用,使用不同的事件将提要中的帖子作为服务页面返回:
constructor(userService: UserService, private ref: ApplicationRef, private zone: NgZone)
...
this.postsSubject.subscribe((post) => {
this.zone.runOutsideAngular(() => { // doesn't do anything
this.posts.push(post);
console.log('postsSubject POST, count is ', this.posts.length);
ref.tick(); // required to update bindings
});
}
控制台显示计数递增,但仅当我添加 ref.tick() 调用时,html 绑定 {{posts.length}} 才会更新...
我想我在某处看到您可以从顶级应用程序组件中为任何组件提供“输入”,这可能是登录用户的方式,但不是其他调用,例如在提要中获取帖子。 ..
【问题讨论】:
-
我不知道,但如果这对你有帮助,那就好了,stackoverflow.com/questions/35500890/…
-
currentUser 是一个 BehaviorSubject。您必须使用异步管道
{{ (currentUser | async)?.value?.name}}订阅它。
标签: typescript angular angular2-changedetection