[英]Pass input to Angular components via router
在 Angular 2 中,我在app.module.ts
中定义了我的路由:
const appRoutes: Routes = [
{
path: '',
component: HomeComponent,
},
{
path: 'admin',
component: AdminComponent,
}
];
我还有一个显示菜单和搜索表单的app.component
。 此app.component
连接到返回events
数组的服务 ( events.service.ts
)。 当搜索表单提交时, app.component
调用服务过滤事件然后抓取它们:
getEvents(): void {
this.eventsService.getEvents().then(events => {this.events = events});
}
onSubmit() {
this.searchTerm = this.model.searchTerm;
this.eventsService.search(this.searchTerm).then(res => this.getEvents());
}
我希望能够将this.events
从app.component
传递到app.module
中指定的两个路由( home
和admin
)。
我的home.component.ts
需要相同的events.service.ts
,并在onNgInit
函数中从中获取事件,但是当通过app.component.ts
中的搜索更新服务中的事件时,在home.component.ts
的初始化已过期。 我希望它们是同步的。
您不能直接将数据作为“输入”传递给路由。 放置在<router-outlet>
“另一侧”的组件在模板中不可见,因此“输入”的概念在这种情况下不适用。
路由器的想法是在路由中编码尽可能多的应用程序状态。 当然,您可以实现某种缓存来避免对同一资源的多次请求,您希望在合理的时间内保持不变。
当然,并不是所有的数据都可以通过路由传输。 例如,您通常只为实体编写某种标识,然后使用 HTTP 根据从路由中读取的 ID 将更多数据带入。
也就是说,您可以将数据保存在服务中。 从您的组件中,将一些数据保存在您注入的服务实例中。 因为服务是单例的,所以当您在用作子路由的组件中注入相同的服务时,您将从父路由中放置数据。
// componentA
this.service.data = data; // from http request, for example
// componentB
this.data = this.service.data;
当然,根据上述操作的时间,可能会发生组件 B 中的代码在组件 A 中的代码之前执行的情况,这意味着您将从Service#data
中获取undefined
。 如果data
是异步获取的,这种情况尤其常见,这通常是 HTTP 请求的情况。
为此,您可以使用 observables,可能是BehvaiorSubject
,以便在您订阅时获取数据。
// service
data$ = new BehaviorSubject<T>(null) // initial value as arg
// component A
this.service.data$.next(data) // from http request, for example
// component B
this.service.data$.subscribe(data => this.data = data)
现在,只要在组件 A 中获取数据,组件 B 中的数据就会更新,尽管单例服务中的data$
可观察到注入到两个组件中。
一定要取消订阅,尽管你也可以在 Angular 中使用async
管道。 在这种情况下,Angular 将为您处理取消订阅,并且在大多数情况下,这是在 Angular 中使用 observables 的首选方式。
从 Angular 7.2.0 开始,您可以使用NavigationExtras通过路由器传递数据
将状态添加到路由定义中:
const appRoutes: Routes = [
{
path: '',
component: HomeComponent,
state:{...}
},
{
path: 'admin',
component: AdminComponent,
}
];
但是,您的应用程序从 app.module.ts 引导,这意味着当应用程序在 app.module.ts 中设置时,服务仍然不可用,儿子您还不能调用服务。
选项 1:使用中间组件,在路由器上加载 HomeComponent_B 或 AdminComponent_B,在该组件上,在模板上加载最终组件<app-homecomponent [events]="dat from services">
选项 2:更好的方法是使用@Lazar Ljubenović建议的 BehaivourSubject
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.