2

在我的 Angular 2 应用程序中,我有一个选项卡区域,用户可以在其中从一组独立但上下文相关的组件中进行选择。当他们点击这些链接之一时,相关组件会根据 routerLink 中定义的内容加载,如下所示:

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

这运作良好。但是,从那时起,我们构建了应用程序以将各种用户选择的过滤器选择保存为 URL 中的参数。这样,当他们重新加载组件时,他们最近的选择仍然可见并应用于数据。因此,在用户做出一些过滤器选择后,URL 可能如下所示:

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

其组件代码如下所示:

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,
        }]);
}

这适用于主要导航方法,这些方法通过路由文件完成,每个方法如下所示:

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

但是,对于我提到的这个选项卡区域,它根据硬编码的 routerLink 参数加载组件。所以我现在意识到,当用户以这种方式导航回组件时,而不是通过我们提供的其他方式之一,它实际上会覆盖 URL 参数——因为它实际上是在加载“page1”——因为这个<a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>

...因此,之前添加的 URL 参数将被清除。

所以,我的问题是,有没有办法可以编辑这段代码:

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

...所以它允许一些动态变量?还是我必须找到一种新方法来处理此选项卡区域中的导航?

4

1 回答 1

5

这是我开始使用的解决方案queryParams

首先,您可以routerLink使用queryParams指令在指令中传递参数:

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

哪里fooParams是一个普通的对象:

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

Angular 会像这样输出这个 url

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

接下来你要做的是设置一种拦截 的方法ActivatedRoute,这样你就可以从 中提取参数的值ActivatedRouteSnapshot。您可以使用解析器或直接在您的组件中执行此操作。在我的示例中,我使用了解析器:

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

然后在路由定义中传递该解析器:

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

然后,PageOneComponent您可以在内部订阅已解析的数据并使用它做任何您想做的事情,例如,使用它设置表单的值并在表单更改时更新 queryParams。


有关完整示例,请查看此plunker

确保在单独的窗口中打开预览,以便您可以在浏览器中看到路线更改。

如果您导航到第 1 页,更改表单中的值,然后导航到第 2 页,然后在浏览器中按回,您可以看到表单中加载的值与 url 中的参数相对应。

于 2017-09-21T14:09:02.997 回答