route - Cambiar un solo parámetro de ruta en la ruta actual en Angular 2
routerlinkactive angular 6 (4)
¿Por qué simplemente no haces esto?
<a [routerLink]="[''./Cmp'', {limit: 10, offset: 10}]">Previous Page</a>
<a [routerLink]="[''./Cmp'', {limit: 10, offset: 20}]">Next Page</a>
¿Es posible cambiar un único parámetro de ruta en la ruta actual, manteniendo todos los demás parámetros? Esto es para uso en un componente de paginación, que se enrutará a una nueva página manteniendo las otras partes de la ruta actual igual.
Algunos ejemplos:
- Página predeterminada a la página 2:
orders?foo=foo&bar=bar
>orders?foo=foo&bar=bar&page=2
- Página predeterminada a la página 2 (niño):
orders/;foo=foo;bar=bar
>orders/;foo=foo;bar=bar;page=2
- Página 2 a 3 en hijo y padre con parámetros:
orders/;foo=foo;page=2?bar=bar
>orders/;foo=foo;page=3?bar=bar
He intentado usar un routerLink
, sin embargo, esto pierde cualquier parámetro adicional que originalmente no forma parte del enlace del router.
También he intentado usar el Router
actual para obtener una Instruction
para la ruta actual, sin embargo, cambiar los parámetros de la Instruction
no parece tener ningún efecto al llamar a navigateByInstruction()
.
Es bastante facil Digamos que tenemos un método en nuestro ListComponent que cambia la página y mantiene todos los demás parámetros intactos (como los parámetros relacionados con la búsqueda; no se puede cambiar la página y se olvida que estábamos buscando algo :):
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
}
Usé el subrayado para asignar un parámetro de página al mapa existente de parámetros de mi objeto privado RouteParams inyectado. Ese mapa se actualiza al navegar, así que todos estamos bien, solo recuerda que no puedes cambiarlo directamente, es imputable.
Aquí está mi implementación de una lista de artículos junto con un componente de paginación usado como una directiva para proporcionar paginación:
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;
}
}
Plantilla de paginación (index.html) - Yo uso bootstrap para el estilo
<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>
Uso en la plantilla de lista de artículos:
...
<pagination *ngIf="list.pages > 1" [(list)]="list" (change)="page($event)" class="text-center"></pagination>
...
El servicio de artículos en mi pequeño proyecto solicita un rango de artículos del servidor usando el encabezado de Rango.
Espero que encuentre útil esta información!
Estaría bien si el activeRoute pudiera devolver un clon simple de la ruta actual [] para ser manipulado antes de llamar a router.navigate (nextroutearray), pero no encontré tal método en la api.
Por lo tanto, centralicé el requisito en un servicio simple, donde puedo analizar el activeRoute actual, + un conjunto de parámetros que se utilizarán para la siguiente ruta. No creo que este código cubra toda la complejidad de la url en una ruta, pero en mi caso, solo uso parámetros en la última parte de la ruta, así que funciona para mí:
El método de servicio se ve así:
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;
}
Entonces puedo usar este método en cualquier componente para que se inyecte mi servicio de sitemap:
setNextTab(tab: string) {
let nextUrl = this.sitemapService.routeFor(this.activatedRoute, { pagetab: tab });
this.router.navigate(nextUrl);
}
Y en el html, el enlace al método setNextTab se ve así:
<li (click)="setNextTab(''myTabName'')">Next tab</li>
puede utilizar la opción de parámetro de consulta en lugar del parámetro que se usa como
en componente de llamada
const navigationExtras: NavigationExtras = {
queryParams: { ''param_id'': 1, ''param_ids'': 2, ''list'':[1,2,3] },
};
this.router.navigate([''/path''], navigationExtras);
en el componente llamado
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));