admin管理员组

文章数量:1297086

In Angular 2, I have my routes defined in app.module.ts:

const appRoutes: Routes = [
  { 
    path: '',
    ponent: HomeComponent,
  },
  {
    path: 'admin',
    ponent: AdminComponent,
  }
];

I also have an appponent which displays the menu and a search form. This appponent is connected to a service (events.service.ts) which returns an array of events. When the search form is submitted, appponent calls the service to filter the events and then grabs them:

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());
}

I would like to be able to pass this.events from the appponent down to the two routes specified in app.module (home and admin).

My homeponent.ts requires the same events.service.ts, and grabs events from it in an onNgInit function, but when the events in the service have been updated via the search in appponent.ts, the events grabbed in the initialisation of homeponent.ts are out of date. I would like them to be synchronised.

In Angular 2, I have my routes defined in app.module.ts:

const appRoutes: Routes = [
  { 
    path: '',
    ponent: HomeComponent,
  },
  {
    path: 'admin',
    ponent: AdminComponent,
  }
];

I also have an app.ponent which displays the menu and a search form. This app.ponent is connected to a service (events.service.ts) which returns an array of events. When the search form is submitted, app.ponent calls the service to filter the events and then grabs them:

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());
}

I would like to be able to pass this.events from the app.ponent down to the two routes specified in app.module (home and admin).

My home.ponent.ts requires the same events.service.ts, and grabs events from it in an onNgInit function, but when the events in the service have been updated via the search in app.ponent.ts, the events grabbed in the initialisation of home.ponent.ts are out of date. I would like them to be synchronised.

Share Improve this question edited Sep 26, 2017 at 15:09 GluePear asked Sep 26, 2017 at 14:59 GluePearGluePear 7,73520 gold badges72 silver badges127 bronze badges 1
  • theres 2 options, passing the data in the route parameters and via an injectable service – mast3rd3mon Commented Sep 26, 2017 at 15:02
Add a ment  | 

2 Answers 2

Reset to default 5

You cannot directly pass data as "input" to the route. Components which are placed "at the other side of" <router-outlet> are not visible in template, hence the notion of an "input" is not applicable in such cases.

The idea of router is to encode as much of application state as possible in the route. Of course, you can implement some sort of caching to avoid multiple requests for the same resource that you expect to stay the same during reasonable amount of time.

Of course, not all data can be transferred through route. For example, you usually write only some sort of identification for an entity, and then use HTTP to bring more data down based on the ID read from the route.

That said, you can keep your data in a service. From your ponent, save some data in a service instance which you've injected. Because services are singletons, when you inject the same service in a ponent which is used as a child route, you'll have the data placed in it from the parent route.

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

// ponentB
this.data = this.service.data;

Of course, depending on the timing of the operations above, it might happen that code in ponent B executes before code in ponent A, which means that you would grab undefined from Service#data. This is especially a mon case if data is fetched asynchronously, which is often the case with HTTP requests.

For this, you can use observables, probably a BehvaiorSubject in order to grab data whenever you subscribe.

// service
data$ = new BehaviorSubject<T>(null) // initial value as arg

// ponent A
this.service.data$.next(data) // from http request, for example

// ponent B
this.service.data$.subscribe(data => this.data = data)

Now your data in ponent B will update as soon as data is fetched in ponent A, though the data$ observable in the singleton service injected in both ponents.

Be sure to unsubscribe as well, although you can use async pipe in Angular too. In that case, Angular will handle the unsubscription for you and in most cases this is the preferred way of using observables in Angular.

Since angular 7.2.0 you can pass data through the router, using NavigationExtras

Add state to the route definition:

const appRoutes: Routes = [
  { 
    path: '',
    ponent: HomeComponent,
    state:{...}
  },
  {
    path: 'admin',
    ponent: AdminComponent,
  }
];

But, your app bootstraps from app.module.ts, this mean that when the app is setting up in app.module.ts the services aren't still available, son you can't call the services yet.

Option 1: Use a intermediate ponent, on the router you load HomeComponent_B or AdminComponent_B, and on that ponent, on the template you load the final ponent <app-homeponent [events]="dat from services">

Option 2: Better approach is use BehaviorSubject as suggested by @Lazar Ljubenović

本文标签: javascriptPass input to Angular components via routerStack Overflow