我正在 Build 一个角度2应用程序 . 自发布以来,文档发生了很大的变化,引起了混乱 . 我能做的最好的事情就是解释我想要做什么(在Angular 1中这很容易)并希望有人可以帮助我 .
我使用JWT创建了一个登录服务 . 登录成功后,我返回一个用户对象 .
我有一个loginComponent(将数据绑定到模板)和loginService(处理https调用)
我有一个维护用户对象的userService .
我有一个userComponent,用于呈现用户数据 .
问题是,一旦用户登录,我不清楚让userService在名为“user”的对象中检索新数据的最佳方法,然后userComponent更新模板上的用户对象 . 只需将观察者放在userService.user对象上,就可以轻松实现角度1 .
我尝试输入和输出无效,eventEmitters,Observables和getter和setter . getter和setter工作,但强迫我将所有内容存储在“val()”中
有人可以告诉我实现这个目标的最佳方法吗?
-
用户组件使用user.firstName,user.lastName等呈现模板 .
-
最初用户是否为空对象
-
登录服务需要设置UserService.user
-
userComponent需要检测更改并更新DOM .
提前致谢!
2 回答
如果我'm not wrong, you are looking for a way to '听你的
UserService.user
中的更改,以便在UserComponent
中进行适当的更新 . 使用Subject
(或BehaviorSubject
)可以很容易地做到这一点 .UserService
中,使用Subject<User>
类型声明属性user
.-Login函数将更新私有
user
主题 .UserComponent
中,订阅UserServive
的user$ observable
来更新视图 .这是工作的plunker:http://plnkr.co/edit/qUR0spZL9hgZkBe8PHw4?p=preview
您可以采取两种不同的方法:
1. Share data via JavaScript reference types
如果在UserService中创建对象
然后,您可以通过它作为JavaScript引用类型来共享该对象 . 注入UserService的任何其他服务或组件都可以访问该
user
对象 . 只要您在服务中使用 only modify the original object (即,您没有指定新对象),所有视图都会在更改后自动更新并显示新数据(因为Angular更改检测的工作方式) . 有no need for any Angular 1-like watchers .
这是一个例子plunker .
在plunker中,它有一个共享的
data
对象而不是共享的user
对象 . 您可以单击一个更改数据按钮,该按钮将在服务上调用changeData()
方法 . 您可以看到AppComponent的视图在服务更改其data
属性时自动更新 . 您不必编写任何代码来使其工作 - 不需要getter,setter,Input,Output / EventEmitter或Observable .视图更新自动发生,因为(默认情况下)角度更改检测每次启动猴子修补的异步事件(例如按钮单击)时都会检查所有模板绑定(如
{{data.prop1}}
) .2. "Push" data using RxJS
@HarryNinh在他的回答中说得很清楚 . 另见Cookbook主题Parent and children communicate via a service . 它显示了如何使用主题来促进沟通"within a family" .
我建议使用BehaviorSubject而不是Subject,因为BehaviorSubject具有"the current value"的概念,这可能适用于此处 . 考虑一下,如果您使用路由并(基于某些用户操作)移动到新路由并创建新组件,您可能希望该新组件能够检查用户的"current value" . 你需要一个BehaviorSubject才能使它工作 . 如果使用常规Subject,则新组件将无法检索当前值,因为Subject的订阅者只能获取新发出的值 .
那么,我们应该使用方法1.还是2.?像往常一样,“这取决于” . 方法1.代码少得多,您不需要了解RxJS(但您需要了解JavaScript引用类型) . 方法2.这些天风靡一时 .
方法2.也可能比1.更有效,但是因为Angular的默认变化检测策略是"check all components",你需要使用
OnPush
变化检测策略和markForCheck()(我不会在这里讨论如何使用它们)使其比方法1更有效 .