简体   繁体   中英

routerLinkActive for dynamic routes by default is active Angular 2

I have two links and url I get dynamically by ngOnInit .

<li><a [routerLink]="welcomeUrl" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">Getting Started</a></li>
<li><a [routerLink]="dashboardUrl" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">Dashboard</a></li>

Here is my component:

ngOnInit() {
        this.dataService.getOptions().subscribe((options: Options) => {
            if (options.mode.toLowerCase() === "live") {
                this.dashboardUrl = '/';
                this.welcomeUrl = 'welcome';
            } else {
                this.dataService.getName().subscribe((name: string) => {
                    this.dashboardUrl = name;
                    this.welcomeUrl = name + '/welcome';
                });
            }
        });
    }

And routes:

const routes: Routes = [
    { path: '', component: DashboardComponent },
    { path: 'welcome', loadChildren: 'app/welcome/welcome.module#WelcomeModule' },
    { path: ':name', component: DashboardComponent },
    { path: ':name/welcome', loadChildren: 'app/welcome/welcome.module#WelcomeModule' },
];

But when I launch app these links are active. They are starting to work fine after click on link that change url.

May be by default these links (urls) are empty and always active? How can I fix that?

First of all, writing [routerLink] (with the [ ] ) makes the directive expect an array, so your code should read:

<a [routerLink]="welcomeUrl" routerLinkActive="active">...</a>

But I think the problem is due to the async nature of your code: routerLinkActive executes before welcomeUrl is set and it can't do its job.

Solution #1: Wrap your links with *ngIf (quick & dirty)

Wrap your links with a test to only display them once the variables are set:

<ul *ngIf="welcomeUrl && dashboardUrl">
  <li><a [routerLink]="welcomeUrl" routerLinkActive="active">Getting Started</a></li>
  <li><a [routerLink]="dashboardUrl" routerLinkActive="active">Dashboard</a></li>
</ul>

Solution #2: Move the async call (more robust but more work)

Another option would be to move your async call — this.dataService.getOptions() — to a point that gets executed before the component containing the routerLinks gets activated.

It's hard to be more specific without knowing how your components are organized, but:

  • If the component containing the routerLinks is a routed component , you could add a resolve param to its route declaration and call this.dataService.getOptions() inside the resolve. The resolve would fetch the "mode" and then pass it to the component via ActivatedRoute.data["mode"] . See the documentation on Resolve: https://angular.io/docs/ts/latest/guide/router.html#resolve-guard
  • If the component containing the routerLinks is a child component of another component, you could call this.dataService.getOptions() inside the parent and pass the "mode" to the child via an @Input .

In both cases, the idea is the same: to figure out the "mode" before activating the component containing the routerLinks, so you can set the welcomeUrl and dashboardUrl variables before routerLinkActive is executed.

To test whether the async call is indeed the cause of you problem, try the *ngIf solution and see if it works.

Try this:

<li>
  <a [routerLink]="dashboardUrl" routerLinkActive="active"
     [routerLinkActiveOptions]="{exact: true,__change_detection_hack__:dashboardUrl}">
    Dashboard
  </a>
</li>

this can help you: https://github.com/angular/angular/issues/18469

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM