通过路由器将输入传递给 Angular 个组件

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 连接到 returns 一个 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.eventsapp.component 传递到 app.module 中指定的两条路线(homeadmin) .

我的 home.component.ts 需要相同的 events.service.ts,并在 onNgInit 函数中从中获取事件,但是当服务中的事件已通过 [=] 中的搜索更新时27=], home.component.ts初始化时抓取的事件已经过期。我希望它们同步。

您不能直接将数据作为 "input" 传递给路由。放置在 "at the other side of" <router-outlet> 中的组件在模板中不可见,因此 "input" 的概念不适用于这种情况。

路由器的思想是在路由中编码尽可能多的应用程序状态。当然,您可以实施某种缓存以避免对您希望在合理时间内保持不变的同一资源的多次请求。

当然,并不是所有的数据都可以通过路由传输。例如,你通常只为一个实体写一些标识,然后根据从路由中读取的标识使用 HTTP 将更多数据带下来。

也就是说,您可以将数据保存在服务中。在您的组件中,将一些数据保存在您注入的服务实例中。因为服务是单例的,所以当您在用作子路由的组件中注入相同的服务时,您将从父路由中将数据放入其中。

// componentA
this.service.data = data; // from http request, for example

// componentB
this.data = this.service.data;

当然,根据上述操作的时机,可能会出现组件B中的代码先于组件A中的代码执行,这意味着您将从Service#data中获取undefined。如果 data 是异步获取的,这种情况尤其常见,HTTP 请求通常就是这种情况。

为此,您可以使用可观察对象,可能是 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)

现在组件 B 中的数据将在组件 A 中获取数据后立即更新,尽管在两个组件中注入的单例服务中的 data$ observable。

请务必取消订阅,尽管您也可以在 Angular 中使用 async 管道。在这种情况下,Angular 将为您处理取消订阅,在大多数情况下,这是在 Angular.

中使用可观察对象的首选方式

从 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: 更好的方法是使用

所建议的 BehaivourSubject