How to use the activated route's data DIRECTLY

2020-02-01 15:44发布

问题:

This one took me a while to figure out, so I hope to save someone's time by sharing the solution in the SO's Q&A way. Here it goes:

Goal

I have an Angular8 web application, where I use the RouterModule to navigate between the components.

Here is how my routes are defined:

const routes: Routes = [
    { path: 'moo', component: AppMooComponent, data: { title: 'Moo Section', desc: 'Moo is the first example component.' } },
    { path: 'boo', component: AppBooComponent, data: { title: 'Boo Section', desc: 'Boo is the second example component.' } },
    { path: 'foo', component: AppFooComponent, data: { title: 'Foo Section', desc: 'Foo is the third example component.' } },
    { path: '', redirectTo: 'moo', pathMatch: 'full' },
];

I would like to be able to use data.title and data.desc (or any defined data for that matter) in my HTML template in the following way:

<ul>
    <li><a [routerLink]="['moo']">Moo</a></li>
    <li><a [routerLink]="['boo']">Boo</a></li>
    <li><a [routerLink]="['foo']">Foo</a></li>
</ul>
<hr>
<h1>{{<something>.data.title}}</h1>
<p>{{<something>.data.desc}}</p>
<hr>
<router-outlet></router-outlet>

Problem

Injecting ActivatedRoute to get the data does not work, because ActivatedRoute is:

A service that is provided to each route component

and the component, containing the router-outlet is not a route component.

Research

I have searched the site and found the following questions discussing a very similar problem:

How can I access an activated child route's data from the parent route's component?

Get route data outside the router outlet

Access activated route data from some other component

Accessing Route data in root component, route data is empty

Angular ActivatedRoute data returns an empty object

However, in my case the emphasize is on direct usage of the route's data in the HTML template, so neither of those possible solutions is suitable (as summarized in How To Get Route Path Parameters In Non-Routed Angular Components):

  • Moving the non-routed component inside of the routed component
  • Using router navigation events
  • Creating an additional service to hold the route path param state and make it available for all other interested components

How to achieve that in the desired way?

回答1:

Solution

I would suggest you to use a template variable reference as shown in the documentation:

#myTemplateVar="outlet"

Then you can access the route's data via the activatedRouteData: Data property of <router-outlet> and use it in the HTML template like this:

<h1>{{myTemplateVar.activatedRouteData.title}}</h1>
<p>{{myTemplateVar.activatedRouteData.desc}}</p>
<hr>
<router-outlet #myTemplateVar="outlet"></router-outlet>

Example

I have prepared a simple example for you on Stackblitz in order to demonstrate the proposed solution.

Result

Here how the result looks like (it is similar for the other routes/components):