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()
.
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));
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>
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>
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)">«</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)">»</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!