【发布时间】:2016-09-19 12:16:28
【问题描述】:
我想,这个问题之前已经讨论过,无论是新的 RC 路由器还是已弃用的路由器。最受欢迎的解决方案似乎是使用服务将数据向下传递到由路由器插座激活的组件。
但是,我想得越多,就越发现自己陷入了并发、可观察对象和事件发射者的地狱。请考虑以下情况:
一条路线是这样调用的:“/car/123/motor/4/sparkcoil”
这意味着:获取 ID 为 4 的电机的火花线圈的数据,该电机又是 ID 为 123 的汽车的一部分。
因此,有 3 个具有嵌套路由的组件,“汽车”组件、“电机”组件和“火花线圈”组件。第一个组件有一个路由器出口,子组件在其中呈现。不太难,目前为止。
让我们做一些假设:
1) 在“电机”组件中,我需要访问汽车数据,在“火花线圈”组件中,我需要同时访问汽车数据和电机数据。
2) 由于数据量巨大,获取汽车的后端调用不会包含有关所有可用电机类型的数据。因此,汽车、电机和火花线圈数据必须在单独的后端调用中获取。
第一个被激活的组件是路线“/car/123”是汽车组件。它注入了一个服务,进行后端调用并返回一个 Observable,组件订阅该 Observable。
然后,第二条路线“/motor/4”被激活。我需要了解父组件获取的汽车对象。稍后,“/sparkcoil”组件被激活,它也需要了解电机和汽车。显然,现在没有办法让它通过 @Input 装饰器传递。常见的建议是:使用服务。好的,所以我将服务 X 注入汽车和电机组件。痛苦来了。如果没有发现自己处于并发事件发射器或可观察者的地狱,我没有令人满意的解决方案来设计服务。
想法1:
汽车和电机组件在名为 fetchMotor(id) 和 fetchCar(id) 的服务上调用一个函数,该函数依次触发 motorFetchedEventEmitter 和 carFetchedEventEmitter 的 next() 方法。电机和 sparkcoil 组件订阅所有 EventEmitters 以获取有关何时获取后端数据的通知。但是,我不知道组件是否订阅了它们触发的 EventEmitter before 或 after。如果之前,一切都很好,如果之后,我需要“重播”发射器(参见 Observable.replay(...))。由于服务及其 EventEmitters 仅实例化一次,因此重放 Observables 意味着我可能会收到很多(不相关的)事件。
想法2:
我会反过来做。在调用火花线圈组件之前,汽车和电机组件保持空闲状态。该组件解析所有路由段,执行相应的后端调用,并通过服务的 EventEmitters 将后端响应传播到“汽车”和“汽车”组件。我承认这种方法对于 RC1 的新组件路由来说适得其反。
考虑到生命周期挂钩,对于这种情况可能有更好的解决方案。根据文档, OnActivate 接口(参见https://angular.io/docs/js/latest/api/router/OnActivate-interface.html) 说,当 onActivate 返回一个承诺时,在承诺解决之前,所有子组件都不会被激活。我认为路由组件没有类似的功能。
有没有人知道如何尽可能优雅地解决这个问题。
提前感谢您的想法。我需要喝杯咖啡! :-?
【问题讨论】:
标签: angularjs routing routes angular