javascript - change - page title angular 4
En Angular, ¿cómo se determina la ruta activa? (28)
¿Cómo se determina cuál es la ruta actualmente activa?
ACTUALIZACIÓN: actualizado según Angular2.4.x
constructor(route: ActivatedRoute) {
route.snapshot.params; // active route''s params
route.snapshot.data; // active route''s resolved data
route.snapshot.component; // active route''s component
route.snapshot.queryParams // The query parameters shared by all the routes
}
NOTA:
Aquí hay muchas respuestas diferentes, y la mayoría han sido válidas en un momento u otro.
El hecho es que lo que funciona ha cambiado varias veces a medida que el equipo de Angular ha cambiado su enrutador.
La versión Router 3.0 que eventualmente será
el
enrutador en Angular rompe muchas de estas soluciones, pero ofrece una solución muy simple propia.
A partir de RC.3, la solución preferida es usar
[routerLinkActive]
como se muestra en
esta respuesta
.
En una aplicación Angular (actual en la versión 2.0.0-beta.0 mientras escribo esto), ¿cómo determina cuál es la ruta actualmente activa?
Estoy trabajando en una aplicación que usa Bootstrap 4 y necesito una forma de marcar los enlaces / botones de navegación como activos cuando su componente asociado se muestra en una etiqueta
<router-output>
.
Me doy cuenta de que podría mantener el estado yo mismo cuando se hace clic en uno de los botones, pero eso no cubriría el caso de tener múltiples rutas en la misma ruta (digamos un menú de navegación principal y un menú local en el componente principal). )
Cualquier sugerencia o enlaces serán apreciados. Gracias.
A continuación se encuentran las respuestas a esta pregunta para todas las versiones de Angular 2 RC lanzadas hasta la fecha:
RC4 y RC3 :
Para aplicar la clase al enlace o antecesor del enlace:
<li routerLinkActive="active"><a [routerLink]="[''/home'']">Home</a></li>
/ home debe ser la URL y no el nombre de la ruta, ya que la propiedad de nombre ya no existe en el objeto de ruta a partir del enrutador v3.
Más información sobre la directiva routerLinkActive en este angular.io/docs/ts/latest/api/router/index/… .
Para aplicar la clase a cualquier div en función de la ruta actual:
- Inyecte el enrutador en el constructor del componente.
- Usuario router.url para la comparación.
p.ej
<nav [class.transparent]="router.url==(''/home'')">
</nav>
RC2 y RC1 :
Use la combinación de router.isRouteActive y class. *. por ejemplo, para aplicar la clase activa basada en la ruta de inicio.
El nombre y la URL se pueden pasar al router.generate.
<li [class.active]="router.isRouteActive(router.generate([''Home'']))">
<a [routerLink]="[''Home'']" >Home</a>
</li>
A continuación se muestra el método que usa RouteData para diseñar los elementos de la barra de menú según la ruta actual:
RouteConfig incluye datos con pestaña (ruta actual):
@RouteConfig([
{
path: ''/home'', name: ''Home'', component: HomeComponent,
data: {activeTab: ''home''}, useAsDefault: true
}, {
path: ''/jobs'', name: ''Jobs'', data: {activeTab: ''jobs''},
component: JobsComponent
}
])
Una pieza de diseño:
<li role="presentation" [ngClass]="{active: isActive(''home'')}">
<a [routerLink]="[''Home'']">Home</a>
</li>
<li role="presentation" [ngClass]="{active: isActive(''jobs'')}">
<a [routerLink]="[''Jobs'']">Jobs</a>
</li>
Clase:
export class MainMenuComponent {
router: Router;
constructor(data: Router) {
this.router = data;
}
isActive(tab): boolean {
if (this.router.currentInstruction && this.router.currentInstruction.component.routeData) {
return tab == this.router.currentInstruction.component.routeData.data[''activeTab''];
}
return false;
}
}
A partir de Angular 8, esto funciona:
<li routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
<a [routerLink]="[''/'']">Home</a>
</li>
{ exact: true }
asegura que coincida con la url.
Aquí hay un ejemplo completo para agregar un estilo de ruta activo en Angular versión
2.0.0-rc.1
que tiene en cuenta las rutas raíz nulas (por ejemplo,
path: ''/''
)
app.component.ts -> Rutas
import { Component, OnInit } from ''@angular/core'';
import { Routes, Router, ROUTER_DIRECTIVES } from ''@angular/router'';
import { LoginPage, AddCandidatePage } from ''./export'';
import {UserService} from ''./SERVICES/user.service'';
@Component({
moduleId: ''app/'',
selector: ''my-app'',
templateUrl: ''app.component.html'',
styleUrls: [''app.component.css''],
providers: [UserService],
directives: [ROUTER_DIRECTIVES]
})
@Routes([
{ path: ''/'', component: AddCandidatePage },
{ path: ''Login'', component: LoginPage }
])
export class AppComponent { //implements OnInit
constructor(private router: Router){}
routeIsActive(routePath: string) {
let currentRoute = this.router.urlTree.firstChild(this.router.urlTree.root);
// e.g. ''Login'' or null if route is ''/''
let segment = currentRoute == null ? ''/'' : currentRoute.segment;
return segment == routePath;
}
}
app.component.html
<ul>
<li [class.active]="routeIsActive(''Login'')"><a [routerLink]="[''Login'']" >Login</a></li>
<li [class.active]="routeIsActive(''/'')"><a [routerLink]="[''/'']" >AddCandidate</a></li>
</ul>
<route-outlet></router-outlet>
Como se menciona en uno de los comentarios de la respuesta aceptada, la directiva
routerLinkActive
también se puede aplicar a un contenedor de la etiqueta
<a>
real.
Entonces, por ejemplo,
con las pestañas de Bootstrap de Twitter
donde la clase activa debe aplicarse a la etiqueta
<li>
que contiene el enlace:
<ul class="nav nav-tabs">
<li role="presentation" routerLinkActive="active">
<a routerLink="./location">Location</a>
</li>
<li role="presentation" routerLinkActive="active">
<a routerLink="./execution">Execution</a>
</li>
</ul>
Con buena pinta !
Supongo que la directiva inspecciona el contenido de la etiqueta y busca una etiqueta
<a>
con la directiva
routerLink
.
Con el nuevo
enrutador angular
, puede agregar un
[routerLinkActive]="[''your-class-name'']"
a todos sus enlaces:
<a [routerLink]="[''/home'']" [routerLinkActive]="[''is-active'']">Home</a>
O el formato simplificado sin matriz si solo se necesita una clase:
<a [routerLink]="[''/home'']" [routerLinkActive]="''is-active''">Home</a>
O un formato aún más simple si solo se necesita una clase:
<a [routerLink]="[''/home'']" routerLinkActive="is-active">Home</a>
Consulte la
directiva
routerLinkActive
mal documentada
para obtener más información.
(Principalmente lo descubrí a través de prueba y error).
ACTUALIZACIÓN: Ahora se puede encontrar una mejor documentación para la directiva
routerLinkActive
here
.
(Gracias a @Victor Hugo Arango A. en los comentarios a continuación).
En Angular2 RC2 puedes usar esta implementación simple
<a [routerLink]="[''/dashboard'']" routerLinkActive="active">Dashboard</a>
esto agregará la clase
active
al elemento con la URL coincidente, lea más sobre esto
angular.io/docs/ts/latest/api/router/index/…
En este momento estoy usando rc.4 con bootstrap 4 y este funciona perfecto para mí:
<li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact:
true}">
<a class="nav-link" [routerLink]="['''']">Home</a>
</li>
Esto funcionará para url: / home
Estaba buscando una manera de usar un navegador de estilo Bootstrap de Twitter con Angular2, pero tuve problemas para aplicar la clase
active
al elemento padre del enlace seleccionado.
¡Descubrí que la solución de @ alex-correia-santos funciona perfectamente!
El componente que contiene sus pestañas tiene que importar el enrutador y definirlo en su constructor antes de que pueda realizar las llamadas necesarias.
Aquí hay una versión simplificada de mi implementación ...
import {Component} from ''angular2/core'';
import {Router, RouteConfig, ROUTER_DIRECTIVES} from ''angular2/router'';
import {HomeComponent} from ''./home.component'';
import {LoginComponent} from ''./login.component'';
import {FeedComponent} from ''./feed.component'';
@Component({
selector: ''my-app'',
template: `
<ul class="nav nav-tabs">
<li [class.active]="_r.isRouteActive(_r.generate([''Home'']))">
<a [routerLink]="[''Home'']">Home</a>
</li>
<li [class.active]="_r.isRouteActive(_r.generate([''Login'']))">
<a [routerLink]="[''Login'']">Sign In</a>
</li>
<li [class.active]="_r.isRouteActive(_r.generate([''Feed'']))">
<a [routerLink]="[''Feed'']">Feed</a>
</li>
</ul>`,
styleUrls: [''app/app.component.css''],
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{ path:''/'', component:HomeComponent, name:''Home'', useAsDefault:true },
{ path:''/login'', component:LoginComponent, name:''Login'' },
{ path:''/feed'', component:FeedComponent, name:''Feed'' }
])
export class AppComponent {
title = ''My App'';
constructor( private _r:Router ){}
}
Estoy usando el enrutador angular
^3.4.7
y todavía tengo problemas con la directiva
routerLinkActive
.
No funciona si tiene varios enlaces con la misma URL, además no parece actualizarse todo el tiempo.
Inspirado por la respuesta de @tomaszbak, creé un pequeño componente para hacer el trabajo
He respondido esto en otra pregunta, pero creo que también podría ser relevante para esta. Aquí hay un enlace a la respuesta original: Angular 2: ¿Cómo determinar la ruta activa con parámetros?
He estado tratando de configurar la clase
activa
sin tener que saber exactamente cuál es la ubicación actual
(usando el nombre de la ruta)
.
La mejor solución a la que he llegado hasta ahora es usar la función
isRouteActive
disponible en la clase
Router
.
router.isRouteActive(instruction): Boolean
toma un parámetro que es un objeto
Instruction
ruta y devuelve
true
o
false
si esa instrucción es verdadera o no para la ruta actual.
Puede generar una
Instruction
ruta mediante el uso de
generar del enrutador (linkParams: Array)
.
LinkParams sigue exactamente el mismo formato que un valor pasado a una directiva
routerLink
(por ejemplo,
router.isRouteActive(router.generate([''/User'', { user: user.id }]))
).
Así es como podría verse el RouteConfig (lo modifiqué un poco para mostrar el uso de los parámetros) :
@RouteConfig([
{ path: ''/'', component: HomePage, name: ''Home'' },
{ path: ''/signin'', component: SignInPage, name: ''SignIn'' },
{ path: ''/profile/:username/feed'', component: FeedPage, name: ''ProfileFeed'' },
])
Y la Vista se vería así:
<li [class.active]="router.isRouteActive(router.generate([''/Home'']))">
<a [routerLink]="[''/Home'']">Home</a>
</li>
<li [class.active]="router.isRouteActive(router.generate([''/SignIn'']))">
<a [routerLink]="[''/SignIn'']">Sign In</a>
</li>
<li [class.active]="router.isRouteActive(router.generate([''/ProfileFeed'', { username: user.username }]))">
<a [routerLink]="[''/ProfileFeed'', { username: user.username }]">Feed</a>
</li>
Esta ha sido mi solución preferida para el problema hasta ahora, también podría ser útil para usted.
La plantilla html pura será como
<a [routerLink]="[''/home'']" routerLinkActive="active">Home</a>
<a [routerLink]="[''/about'']" routerLinkActive="active">About us</a>
<a [routerLink]="[''/contact'']" routerLinkActive="active">Contacts</a>
La solución simple para los usuarios de angular 5 es simplemente agregar
routerLinkActive
al
routerLinkActive
de la lista.
Una directiva
routerLinkActive
está asociada con una ruta a través de una directiva
routerLink
.
Toma como entrada una matriz de clases que agregará al elemento al que está adjunto si su ruta está actualmente activa, de esta manera:
<li class="nav-item"
[routerLinkActive]="[''active'']">
<a class="nav-link"
[routerLink]="[''home'']">Home
</a>
</li>
Lo anterior agregará una clase de activo a la etiqueta de anclaje si actualmente estamos viendo la ruta de inicio.
Otra solución alternativa. Mucho más fácil en Angular Router V3 Alpha. inyectando el enrutador
import {Router} from "@angular/router";
export class AppComponent{
constructor(private router : Router){}
routeIsActive(routePath: string) {
return this.router.url == routePath;
}
}
uso
<div *ngIf="routeIsActive(''/'')"> My content </div>
Para la versión angular 4+, no necesita usar ninguna solución compleja.
Simplemente puede usar
[routerLinkActive]="''is-active''"
.
Para un ejemplo con el enlace de navegación bootstrap 4:
<ul class="navbar-nav mr-auto">
<li class="nav-item" routerLinkActive="active">
<a class="nav-link" routerLink="/home">Home</a>
</li>
<li class="nav-item" routerLinkActive="active">
<a class="nav-link" routerLink="/about-us">About Us</a>
</li>
<li class="nav-item" routerLinkActive="active">
<a class="nav-link " routerLink="/contact-us">Contact</a>
</li>
</ul>
Para marcar rutas
routerLinkActive
se puede usar
routerLinkActive
<a [routerLink]="/user" routerLinkActive="some class list">User</a>
Esto también funciona en otros elementos como
<div routerLinkActive="some class list">
<a [routerLink]="/user">User</a>
</div>
Si las coincidencias parciales también deben marcarse, use
routerLinkActive="some class list" [routerLinkActiveOptions]="{ exact: false }"
Hasta donde sé
exact: false
será el valor predeterminado en RC.4
Pequeña mejora a la respuesta de @ alex-correia-santos basada en https://github.com/angular/angular/pull/6407#issuecomment-190179875
import {Router, RouteConfig, ROUTER_DIRECTIVES} from ''angular2/router'';
// ...
export class App {
constructor(private router: Router) {
}
// ...
isActive(instruction: any[]): boolean {
return this.router.isRouteActive(this.router.generate(instruction));
}
}
Y úsalo así:
<ul class="nav navbar-nav">
<li [class.active]="isActive([''Home''])">
<a [routerLink]="[''Home'']">Home</a>
</li>
<li [class.active]="isActive([''About''])">
<a [routerLink]="[''About'']">About</a>
</li>
</ul>
Puede verificar la ruta actual inyectando el objeto
Location
en su controlador y verificando la
path()
, así:
class MyController {
constructor(private location:Location) {}
... location.path(); ...
}
Tendrás que asegurarte de importarlo primero:
import {Location} from "angular2/router";
Luego puede usar una expresión regular para hacer coincidir la ruta que se devuelve para ver qué ruta está activa.
Tenga en cuenta que la clase
Location
devuelve una ruta normalizada, independientemente de la Estrategia de
LocationStrategy
que esté utilizando.
Entonces, incluso si está utilizando
HashLocationStragegy
las rutas devueltas seguirán teniendo la forma
/foo/bar
no
#/foo/bar
Resolví un problema que encontré en este
link
y descubrí que hay una solución simple para su pregunta.
En su lugar, podría usar
router-link-active
en sus estilos.
@Component({
styles: [`.router-link-active { background-color: red; }`]
})
export class NavComponent {
}
Solo pensé que agregaría un ejemplo que no usa ningún mecanografiado:
<input type="hidden" [routerLink]="''home''" routerLinkActive #home="routerLinkActive" />
<section *ngIf="home.isActive"></section>
La variable
routerLinkActive
está vinculada a una variable de plantilla y luego se reutiliza según sea necesario.
Desafortunadamente, la única advertencia es que no puede tener todo esto en el elemento
<section>
ya que
#home
debe resolverse
antes de
que el analizador presione
<section>
.
Solución para Angular2 RC 4:
import {containsTree} from ''@angular/router/src/url_tree'';
import {Router} from ''@angular/router'';
export function isRouteActive(router: Router, route: string) {
const currentUrlTree = router.parseUrl(router.url);
const routeUrlTree = router.createUrlTree([route]);
return containsTree(currentUrlTree, routeUrlTree, true);
}
Una instancia de la clase Router es en realidad un Observable y devuelve la ruta actual cada vez que cambia. Así es como lo hago:
export class AppComponent implements OnInit {
currentUrl : string;
constructor(private _router : Router){
this.currentUrl = ''''
}
ngOnInit() {
this._router.subscribe(
currentUrl => this.currentUrl = currentUrl,
error => console.log(error)
);
}
isCurrentRoute(route : string) : boolean {
return this.currentUrl === route;
}
}
Y luego en mi HTML:
<a [routerLink]="[''Contact'']" class="item" [class.active]="isCurrentRoute(''contact'')">Contact</a>
Usar
routerLinkActive
es bueno en casos simples, cuando hay un enlace y desea aplicar algunas clases.
Pero en casos más complejos donde es posible que no tenga un routerLink o donde necesite algo más, puede crear y usar una
tubería
:
@Pipe({
name: "isRouteActive",
pure: false
})
export class IsRouteActivePipe implements PipeTransform {
constructor(private router: Router,
private activatedRoute: ActivatedRoute) {
}
transform(route: any[], options?: { queryParams?: any[], fragment?: any, exact?: boolean }) {
if (!options) options = {};
if (options.exact === undefined) options.exact = true;
const currentUrlTree = this.router.parseUrl(this.router.url);
const urlTree = this.router.createUrlTree(route, {
relativeTo: this.activatedRoute,
queryParams: options.queryParams,
fragment: options.fragment
});
return containsTree(currentUrlTree, urlTree, options.exact);
}
}
entonces:
<div *ngIf="[''/some-route''] | isRouteActive">...</div>
y no olvide incluir la tubería en las dependencias de las tuberías;)
Y en la última versión de angular, simplemente puede verificar
router.isActive(routeNameAsString)
.
Por ejemplo, vea el siguiente ejemplo:
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item" [class.active] = "router.isActive(''/dashboard'')">
<a class="nav-link" href="#">داشبورد <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item" [class.active] = "router.isActive(route.path)" *ngFor="let route of (routes$ | async)">
<a class="nav-link" href="javascript:void(0)" *ngIf="route.childRoutes && route.childRoutes.length > 0"
[matMenuTriggerFor]="menu">{{route.name}}</a>
<a class="nav-link" href="{{route.path}}"
*ngIf="!route.childRoutes || route.childRoutes.length === 0">{{route.name}}</a>
<mat-menu #menu="matMenu">
<span *ngIf="route.childRoutes && route.childRoutes.length > 0">
<a *ngFor="let child of route.childRoutes" class="nav-link" href="{{route.path + child.path}}"
mat-menu-item>{{child.name}}</a>
</span>
</mat-menu>
</li>
</ul>
<span class="navbar-text mr-auto">
<small>سلام</small> {{ (currentUser$ | async) ? (currentUser$ | async).firstName : ''کاربر'' }}
{{ (currentUser$ | async) ? (currentUser$ | async).lastName : ''میهمان'' }}
</span>
</div>
Y asegúrese de no olvidarse de inyectar enrutador en su componente.
comience importando RouterLinkActive en sus archivos .ts
importar {RouterLinkActive} desde ''@ angular / router'';
Ahora use RouterLinkActive en su HTML
<span class="" routerLink ="/some_path" routerLinkActive="class_Name">Value</span></a>
proporcione algunos CSS a la clase "class_Name", ya que cuando este enlace esté activo / haga clic, encontrará esta clase en el intervalo durante la inspección.
supongamos que desea agregar CSS a mi estado / pestaña activa. Use routerLinkActive para activar su enlace de enrutamiento.
nota: ''activo'' es mi nombre de clase aquí
<style>
.active{
color:blue;
}
</style>
<a routerLink="/home" [routerLinkActive]="[''active'']">Home</a>
<a routerLink="/about" [routerLinkActive]="[''active'']">About</a>
<a routerLink="/contact" [routerLinkActive]="[''active'']">Contact</a>
Router
en Angular 2 RC ya no define
isRouteActive
y
generate
métodos.
urlTree
: devuelve el árbol de url actual.
createUrlTree(commands: any[], segment?: RouteSegment)
: aplica una matriz de comandos al árbol de url actual y crea un nuevo árbol de url.
Intenta seguir
<li
[class.active]=
"router.urlTree.contains(router.createUrlTree([''/SignIn'', this.routeSegment]))">
aviso,
routeSegment : RouteSegment
debe inyectarse en el constructor del componente.