Modifier un paramètre de route unique sur la route actuelle en angle 2

est-il possible de changer un seul paramètre de route dans la route courante, tout en conservant tous les autres paramètres? Ceci est pour une utilisation dans un composant de pagination, qui va conduire à une nouvelle page tout en gardant les autres parties de la route actuelle le même.

Quelques exemples:

  • page par défaut à la page 2:orders?foo=foo&bar=bar>orders?foo=foo&bar=bar&page=2
  • page par défaut à la page 2 (enfant):orders/;foo=foo;bar=bar > orders/;foo=foo;bar=bar;page=2
  • Page 2 de 3 sur l'enfant et le parent avec des paramètres: orders/;foo=foo;page=2?bar=bar>orders/;foo=foo;page=3?bar=bar

j'ai essayé d'utiliser un routerLink, cependant cela perd tous les paramètres supplémentaires qui ne font pas initialement partie du lien du routeur.

j'ai aussi essayé d'utiliser le courant Router pour obtenir un Instruction pour le chemin courant, en modifiant toutefois les paramètres de Instruction ne semble pas avoir d'effet lors de l'appel de navigateByInstruction().

22
demandé sur Rookian 2016-01-29 15:05:28

4 réponses

vous pouvez utiliser l'option de paramètre de requête au lieu du paramètre il est utilisé comme

dans le composant d'appel

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

dans le composant appelé

  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
répondu Sunil Kumar 2017-09-01 11:19:37

je serait bien si le activeRoute pourrait revenir un simple clone de l'itinéraire actuel [] pour être manipulé avant d'appeler à un routeur.naviguer(nextroutearray), mais je n'ai pas trouvé une telle méthode dans l'api.

j'ai donc centralisé l'exigence en un service simple, où je peux analyser l'activeRoute actuelle, + un ensemble de paramètres à utiliser pour la route suivante. Je ne pense pas que ce code couvrira toute la complexité de l'url dans une route, mais dans mon cas, je n'utilise que des paramètres sur la dernière partie de l'itinéraire, de sorte qu'il fonctionne pour moi:

La méthode de service ressemble à ceci:

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;
}

alors je peux utiliser cette méthode dans n'importe quel composant pour obtenir mon service sitemap injecté:

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

et dans le html, le lien vers la méthode setNextTab ressemble à ceci:

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

2
répondu Kjeld Poulsen 2017-12-17 09:46:46

Pourquoi vous n'avez simplement pas le faire:

<a [routerLink]="['./Cmp', {limit: 10, offset: 10}]">Previous Page</a>
<a [routerLink]="['./Cmp', {limit: 10, offset: 20}]">Next Page</a>
0
répondu Vlado Tesanovic 2016-01-29 12:45:33

C'est assez facile. Disons que nous avons une méthode dans notre ListComponent qui change la page et garde tous les autres paramètres intacts (comme les paramètres liés à la recherche - ne peut pas changer la page et oublier que nous cherchions quelque chose:):

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
}

J'ai utilisé Underscore pour assigner un paramètre de page à la carte existante des paramètres de mon objet privé, injecté RouteParams. Cette carte est mise à jour sur naviguer donc nous sommes tous bien, rappelez-vous juste que vous ne pouvez pas la changer directement, il est imutable.

Voici mon implémentation d'une liste d'articles avec un composant de pagination utilisé comme directive pour fournir la pagination:

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;
    }
}

modèle de Pagination (index.html) - j'utilise bootstrap pour le style

<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>

Utilisation de l'article le modèle de liste:

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

le service d'article dans mon petit projet demande une gamme d'articles de la serveur à l'aide de la Gamme d'en-tête.

j'Espère que vous trouverez ce utile!

0
répondu Kesarion 2016-05-22 16:44:55