web-dev-qa-db-ja.com

Angular 2で現在のルートの単一のルートパラメータを変更します

他のすべてのパラメーターを保持しながら、現在のルートの単一のルートパラメーターを変更することは可能ですか?これはページングコンポーネントで使用するためのもので、現在のルートの他の部分を同じに保ちながら、新しいページにルーティングします。

いくつかの例:

  • デフォルトのページからページ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のパラメーターを変更しても、navigateByInstruction()

26
Robert Davey

次のように使用するパラメータの代わりに、クエリパラメータオプションを使用できます。

コンポーネントの呼び出し中

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));
2
Sunil Kumar

ActiveRouteがrouter.navigate(nextroutearray)を呼び出す前に操作される現在のルート[]の単純なクローンを返すことができればいいのですが、そのようなメソッドが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
Kjeld Poulsen

なぜこれをしないのか:

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

とても簡単です。 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ヘッダーを使用して、サーバーに一連の記事を要求します。

これがお役に立てば幸いです。

0
Kesarion