在Angular 2中更改当前路径上的单个路径参数

时间:2016-01-29 12:05:29

标签: angular angular2-routing angular-routing

是否可以更改当前路线中的单个路线参数,同时保留所有其他参数? 这是用于分页组件,它将路由到新页面,同时保持当前路由的其他部分相同。

一些例子:

  • 第2页的默认页面:orders?foo=foo&bar=bar> orders?foo=foo&bar=bar&page=2
  • 第2页(儿童)的默认页面:orders/;foo=foo;bar=bar> orders/;foo=foo;bar=bar;page=2
  • 有关参数的儿童和家长的第2页至第3页:orders/;foo=foo;page=2?bar=bar> orders/;foo=foo;page=3?bar=bar

我尝试使用routerLink,但这会丢失原本不属于路由器链接的任何其他参数。

我还尝试使用当前Router为当前路径获取Instruction,但是在调用{{}时,更改Instruction的参数似乎没有任何影响1}}。

5 个答案:

答案 0 :(得分:2)

您可以使用查询参数选项而不是像

那样使用参数

调用组件

const navigationExtras: NavigationExtras = {
  queryParams: { 'param_id': 1, 'param_ids': 2, 'list':[1,2,3] },
};
this.router.navigate(['/path'], navigationExtras);

在被调用的组件中

  this.route.queryParamMap.map(params =>  params.get('param_id') || 
    'None').subscribe(v => console.log(v));
  this.route.queryParamMap.map(params =>  params.get('param_ids') || 
        'None').subscribe(v => console.log(v));
  this.route.queryParamMap.map(params =>  params.getAll('list') || 
            'None').subscribe(v => console.log(v));

答案 1 :(得分:2)

如果activeRoute在调用router.navigate(nextroutearray)之前可以返回当前route []的简单克隆,我会很高兴,但我没有在api中找到这样的方法。

因此我将需求集中到一个简单的服务中,我可以解析当前的activeRoute,+一组用于下一个路由的参数。我不认为这段代码会覆盖路由中url的所有复杂性,但在我的情况下,我只在路由的最后部分使用参数,所以它对我有用:

服务方法如下所示:

routeFor(activeRoute: ActivatedRoute, params: any): any[] {
    let result = [];
    result.push('/');
    for (var i = 0; i < activeRoute.pathFromRoot.length; i++) {
        activeRoute.pathFromRoot[i].snapshot.url.forEach(r => result.push(r.path));
    }

    let currentParams = activeRoute.pathFromRoot[activeRoute.pathFromRoot.length - 1].snapshot.url[0].parameters;
    for (var n in currentParams) {
        if (currentParams.hasOwnProperty(n) && !params.hasOwnProperty(n)) {
            params[n] = currentParams[n];
        }
    }

    result.push(params);
    return result;
}

然后我可以在任何组件中使用此方法来获取我的站点地图服务:

setNextTab(tab: string) {
    let nextUrl = this.sitemapService.routeFor(this.activatedRoute, { pagetab: tab });
    this.router.navigate(nextUrl);
}

在html中,setNextTab方法的链接如下所示:

<li (click)="setNextTab('myTabName')">Next tab</li>

答案 2 :(得分:0)

为什么你根本不这样做:

<a [routerLink]="['./Cmp', {limit: 10, offset: 10}]">Previous Page</a>
<a [routerLink]="['./Cmp', {limit: 10, offset: 20}]">Next Page</a>

答案 3 :(得分:0)

这很容易。让我们说我们的ListComponent中有一个方法可以更改页面并保持所有其他参数不变(比如搜索相关参数 - 无法更改页面而忘记我们正在搜索某些内容:):

page (page) {
    this.list.page = page;
    this._router.navigate([this.list.route, _.assign(this._params.params, { page: page })]);
    this.update(); // Update your list of items here
}

我使用Underscore将页面参数分配给我的私有注入RouteParams对象的现有参数映射。该地图会在导航时更新,以便我们保持良好状态,只需记住您无法直接更改,这是不可改变的。

以下是我对文章列表的实现以及用作提供分页的指令的分页组件:

ArticleListComponent:

@Component({
    selector: 'articles',
    templateUrl: './article/list/index.html',
    directives: [PaginationComponent],
    providers: [ArticleService]
})
export class ArticleListComponent implements OnInit {
    list: ArticleList = new ArticleList;

    private _urlSearchParams: URLSearchParams = new URLSearchParams;

    constructor (
        private _article: ArticleService,
        private _router: Router,
        private _params: RouteParams,
        private _observable: ObservableUtilities
    ) {}

    update () {
        this._observable.subscribe(this._article.retrieveRange(this.list));
    }

    ngOnInit () {
        let page = this._params.get("page");
        if(page) {
            this.list.page = Number(page);
        }

        // check for size in cookie 'articles-per-page'

        let title = this._params.get("title");
        if (title) {
            this.list.title = title;
        }

        this.update();
    }

    size (size: number) {
        // set cookie 'articles-per-page'
    }

    page (page) {
        this.list.page = page;
        this._router.navigate([this.list.route, _.assign(this._params.params, { page: page })]);
        this.update();
    }

    search () {
        this.list.page = 1;
        let params = _.pick({
            title: this.list.title
        }, _.identity);
        this._router.navigate([this.list.route, params ]);
    }
}

PaginationComponent:

import { Component, Input, Output, EventEmitter, OnInit } from 'angular2/core';
import { RouteParams } from 'angular2/router';
import  _ from 'underscore';

import { List } from '../common/abstract';

@Component({
    selector: 'pagination',
    templateUrl: './pagination/index.html'
})
export class PaginationComponent implements OnInit {
    @Input() list: List;
    @Output() change  = new EventEmitter<number>();

    pages: Array<number> = [];

    constructor(
        private _params: RouteParams
    ) {}

    ngOnInit () {
        this.pages = _.range(1, this.list.pages + 1);
    }

    onClick (page: number) {
        if (page > 0 && page <= this.list.pages) {
            this.change.emit(page);
        }
        return false;
    }

    href (page: number) {
        return `${this.list.uri}?${_.map(_.assign(this._params.params, { page: page }), (value, param) => `${param}=${value}`).join('&')}`;
    }

    first (page) {
        return page == 1 ? 1 : null;
    }

    last(page) {
        return page == this.list.pages ? this.list.pages : null;
    }
}

分页模板(index.html) - 我使用bootstrap进行样式化

<div>
        <ul class="pagination">
            <li [class.disabled]="first(list.page)"><a (click)="onClick(list.page - 1)" [attr.href]="href(list.page - 1)">&laquo;</a></li>

            <template ngFor let-page [ngForOf]="pages">
                <li *ngIf="(page >= list.page - 2 && page <= list.page + 2) || first(page) || last(page)" [ngSwitch]="(page != list.page - 2 && page != list.page + 2) || first(page) || last(page)" [class.active]="page == list.page">
                    <a *ngSwitchWhen="true" (click)="onClick(page)" [attr.href]="href(page)">{{page}}</a>
                    <a *ngSwitchDefault (click)="onClick(page)" [attr.href]="href(page)">...</a>
                </li>
            </template>

            <li [class.disabled]="last(list.page)"><a (click)="onClick(list.page + 1)" [attr.href]="href(list.page + 1)">&raquo;</a></li>
        </ul>
    </div>

文章列表模板中的用法:

...
<pagination *ngIf="list.pages > 1" [(list)]="list" (change)="page($event)" class="text-center"></pagination>
...

我的小项目中的文章服务使用Range标题从服务器请求一系列文章。

希望您觉得这很有帮助!

答案 4 :(得分:0)

使用 if语句切换大小写来推送参数

if(yourchild == child1){
    params = { 
      parameter1: parameter1, 
      parameter2: parameter2,
    }
} else (yourchild == child2){
    params = { 
      parameter1: parameter1, 
      parameter2: parameter2,
      parameter3: parameter3
    }
}
this.router.navigate([`/yourparent/${yourchild}`], { queryParams: params });