最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Handling Dynamic URL Params via RouterLink in Angular App - Stack Overflow

programmeradmin10浏览0评论

In my Angular 2 app I have a tab area where users can select from a group of independent, but contextually related ponents. When they click on one of these links, the relevant ponent loads according to what's defined in the routerLink, like this:

<a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>

This was working well. However, since then we've built the app to save various user-selected filter selections as params in the URL. This way when they re-load the ponent, they'll have their most recent selections still visible and applied to the data. So the URL might look like this after the user had made some filter selections:

;language_filter=true;language_selection=English

The ponent code for this looks like this:

public changePage(page, value, type, body)
{
    this.onUserSelection(value, type, body, page);

    this.route.params.subscribe(
        (params: any) => {
            this.page = params['page'];
            this.language_filter = params['language_filter'];
            this.language_selection = params['language_selection'];
        }
    );
    this.router.navigate(
        ['/page1', {
            page: page,
            language_filter: this.language_filter,
            language_selection: this.language_selection,
        }]);
}

This works well for the main navigation methods, that are acplished via a routing file, where each one looks like this:

{ path: 'page1', ponent: Page1Component, canActivate: [AuthGuard], data: {contentId: 'page1'} }

However, for this tab area I mentioned, it's loading ponents according to a hard-coded routerLink param. So I realize now that when a user navigates BACK to a ponent that way, as opposed to via one of the other ways we make available, it actually overrides the URL params - because it's literally loading "page1" -- because of this <a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>

... and thus the URL params that had been added previously are wiped out.

So, my question is, is there a way I can edit this code:

<a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>

... so it allows for some dynamic variables? Or do I have to find a new way to handle the navigation in this tab area?

In my Angular 2 app I have a tab area where users can select from a group of independent, but contextually related ponents. When they click on one of these links, the relevant ponent loads according to what's defined in the routerLink, like this:

<a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>

This was working well. However, since then we've built the app to save various user-selected filter selections as params in the URL. This way when they re-load the ponent, they'll have their most recent selections still visible and applied to the data. So the URL might look like this after the user had made some filter selections:

http://somesite./page1;language_filter=true;language_selection=English

The ponent code for this looks like this:

public changePage(page, value, type, body)
{
    this.onUserSelection(value, type, body, page);

    this.route.params.subscribe(
        (params: any) => {
            this.page = params['page'];
            this.language_filter = params['language_filter'];
            this.language_selection = params['language_selection'];
        }
    );
    this.router.navigate(
        ['/page1', {
            page: page,
            language_filter: this.language_filter,
            language_selection: this.language_selection,
        }]);
}

This works well for the main navigation methods, that are acplished via a routing file, where each one looks like this:

{ path: 'page1', ponent: Page1Component, canActivate: [AuthGuard], data: {contentId: 'page1'} }

However, for this tab area I mentioned, it's loading ponents according to a hard-coded routerLink param. So I realize now that when a user navigates BACK to a ponent that way, as opposed to via one of the other ways we make available, it actually overrides the URL params - because it's literally loading "page1" -- because of this <a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>

... and thus the URL params that had been added previously are wiped out.

So, my question is, is there a way I can edit this code:

<a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>

... so it allows for some dynamic variables? Or do I have to find a new way to handle the navigation in this tab area?

Share Improve this question edited Sep 20, 2017 at 21:56 Muirik asked Sep 20, 2017 at 20:43 MuirikMuirik 6,28910 gold badges68 silver badges132 bronze badges 5
  • have you tried using queryParams? – Osman Cea Commented Sep 20, 2017 at 20:59
  • In routerLink you mean? Have an example of what that would look like? – Muirik Commented Sep 20, 2017 at 21:01
  • Give me some time to set up an example... but the basics is that you can append some params to your route (no need to define them in the route definition) as a plain object with the queryParams directive... and then use a resolver in your smart ponent to capture the route snapshot, subscribe to it inside your ponent and update your forms and child ponents on ngOnInit. Then you can do stuff like: <a routerLink="/foo" [queryParams]="{animal:'dog';breed:'poodle'}">Link</a> and the route it will output will look like: localhost:4200/foo?animal=dog&breed=poodle – Osman Cea Commented Sep 20, 2017 at 21:20
  • Look forward to see what this would look like - thanks! – Muirik Commented Sep 20, 2017 at 21:38
  • Could you share a little bit of the main structure of that particular part of your project? so basically my example resembles what you're trying to achieve – Osman Cea Commented Sep 20, 2017 at 21:40
Add a ment  | 

1 Answer 1

Reset to default 7

Here is the solution I came to using queryParams.

First, you can pass parameters in your routerLink directive using the queryParams directive:

<a routerLink="/page1" [queryParams]="fooParams">Page 1</a>
<a routerLink="/page2">Page 2</a>
<router-outlet></router-outlet>

where fooParams is a plain object:

export class MainComponent {
  fooParams = {
    language_filter: true,
    language_selection: 'english'
  }
}

Angular will output this url like

href="localhost:4200/page1?language_filter=true&language_selection=english"

What you have to do next, is set up a way to intercept the ActivatedRoute, so you can extract the values of the params from the ActivatedRouteSnapshot. You can do this either using a resolver or directly in your ponent. In my example I used a resolver:

@Injectable()
export class RoutingResolve implements Resolve<any> {
  resolve(routeSnapshot: ActivatedRouteSnapshot) {
    const { language_filter, language_selection } = routeSnapshot.queryParams;
    return { language_filter, language_selection };
  }
}

And then pass that resolver in the route definition:

const ROUTES: Routes = [
  { 
    path: 'page1',
    ponent: PageOneComponent,
    // In this route we define a resolver so we can intercept the 
    // activatedRoute snapshot before the ponent is loaded
    resolve: {
      routing: RoutingResolve
    }
  },
  { 
    path: 'page2',
    ponent: PageTwoComponent
  }
];

Then, inside PageOneComponent you can subscribe to the resolved data and do whatever you want with it, like for example, setting the value of a form with it and updating the queryParams on form change.


For the full example, check out this plunker

Make sure to open the preview in a separate window, so you can see the route changes in your browser.

If you navigate to Page 1, change the values in the form, then navigate to Page 2, and then press back in your browser, you can see the values loaded in the form correspond to the params in the url.

发布评论

评论列表(0)

  1. 暂无评论