Angular-ui-enrutador: estados ui-sref-active y anidado

82

Estoy usando angular-ui-routerestados anidados en mi aplicación y también tengo una barra de navegación. La barra de navegación está escrita a mano y se utiliza ui-sref-activepara resaltar el estado actual. Es una barra de navegación de dos niveles.

Ahora, cuando esté dentro, digamos que Products / Categoriesme gustaría que se resalten tanto Products(en el nivel 1) como Categories(en el nivel 2). Sin embargo, al usar ui-sref-active, si estoy en el estado Products.Categories, solo se resalta ese estado, no Products.

¿Hay alguna forma de Productsresaltar en ese estado?

paj28
fuente

Respuestas:

139

En lugar de esto-

<li ui-sref-active="active">
    <a ui-sref="posts.details">Posts</a>
</li>

Puedes hacerlo-

<li ng-class="{active: $state.includes('posts')}">
    <a ui-sref="posts.details">Posts</a>
</li>

Actualmente no funciona. Hay una discusión en curso aquí ( https://github.com/angular-ui/ui-router/pull/927 ) y se agregará pronto.

ACTUALIZAR:

Para que esto funcione, $statedebe estar disponible a la vista.

angular.module('xyz').controller('AbcController', ['$scope', '$state', function($scope, $state) {
   $scope.$state = $state;
}]);

Más información

ACTUALIZAR [2]:

A partir de la versión 0.2.11, funciona fuera de la caja. Verifique el problema relacionado: https://github.com/angular-ui/ui-router/issues/818

Rifat
fuente
1
¿Lo hizo $stateespecíficamente disponible en el alcance, como este $rootScope.$state = $state?
JacobF
1
@jvannistelrooy Sí. Por lo general, no pongo nada, $rootScopepero este es una excepción.
Rifat
2
Gracias por publicar esta respuesta. Funcionó perfectamente para mi uso. Terminé mapeando el método de inclusión en el alcance de mi controlador ( $scope.includes = $state.includes) en lugar de adjuntar el archivo $state.
richleland
31

Esta es una opción para cuando anida varios estados que no están relacionados jerárquicamente y no tiene un controlador disponible para la vista. Puede utilizar el filtro UI-Router includedByState para comparar su estado actual con cualquier número de estados con nombre.

<a ui-sref="production.products" ng-class="{active: ('production.products' | 
includedByState) || ('planning.products' | includedByState) || 
('production.categories' | includedByState) || 
('planning.categories' | includedByState)}">
  Items
</a>

TL; DR: ¿Los estados con nombre múltiples, no relacionados, necesitan aplicar una clase activa en el mismo enlace y usted no tiene controlador? Utilice includedByState .

Donutself
fuente
La mejor solución si está creando enlaces de menú que no siguen la jerarquía de State. Además, si está creando un elemento de menú principal en el enlace de menú y no desea crear otro Statesolo por el hecho de usar la ui-sref-activefunción. Creo que Stateestán diseñados para diseñar HTML, no para usar en enlaces de menú.
Barun
También funciona en 1.0.0-beta.1, útil para esos enlaces de menú como se indicó anteriormente. Tenía una barra lateral que hace referencia a uno de los 4 estados secundarios de un estado abstracto principal. Nombrar solo la parte del nombre del estado abstracto funciona como se esperaba cuando se cambia entre los 4 estados hermanos.
rccursach
Podrías colocar toda esta lógica en una función :)
Coder
17

Esta es la solucion:

<li class="myNonActiveStyle" ui-sref-active="myActiveStyle">
     <a ui-sref="project.details">Details</a>
</li>

Editar:

Lo anterior solo funciona para la ruta de ruta exacta y no aplicará activeStyle a las rutas anidadas. Esta solución debería funcionar para esto:

<a data-ui-sref="root.parent" data-ng-class="{ active: $state.includes('root.parent') }">Link</a>
Holanda Risley
fuente
tengo cuatro enlaces en los que quiero agregar una clase activa cuando se selecciona uno de ellos, lo que tengo que hacer para eso. @ holland
Jot Dhaliwal
¿O podría intentar simplemente agregar data-ng-class="{ active: $state.includes('root.parent') a cada uno de los enlaces? ¿Dónde activeestá el nombre de la clase?
Holland Risley
Me salvé el tiempo ... Gracias
choz
11

Digamos que el árbol de URL es el siguiente:

app (for home page) -> app.products -> app.products.category

el uso:

<li ui-sref-active="active">
    <a ui-sref="app.products">Products</a>
</li>

Ahora, al presionar el products: solo estarán activos los productos.

si pulsas category: tanto los productos como la categoría estarán activos.

si desea que solo la categoría esté activa si la presiona, debe usar: ui-sref-active-eqen los productos, lo que significa que solo estará activa y no sus hijos.

el uso adecuado en app.js:

angular.module('confusionApp', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
        $stateProvider

            // route for the home page
            .state('app', {
                url:'/',
                views: { ... }
            })

            // route for the aboutus page
            .state('app.products', {
                url:'products',
                views: { ... }
            })

            // route for the contactus page
            .state('app.products.category', {
                url:'category',
                views: { ... }
            })

        $urlRouterProvider.otherwise('/');
    });
Edan Chetrit
fuente
1
¡Debe marcarse como la respuesta correcta! ¡Gracias, ui-sref-active-eqfunciona perfectamente!
Maxime Lafarie
2

Tan simple, paso 1: agregue un controlador para su barra de navegación o en su controlador existente donde se incluye la barra de navegación agregue lo siguiente

app.controller('navCtrl', ['$scope', '$location', function($scope, $location) {
        $scope.isActive = function(destination) {
        return destination === $location.path();
    }

}]);

Paso 2: en la barra de navegación

<li ng-class="{active: isActive('/home')}"><a ui-sref="app.home">Browse Journal</a></li>

Eso es.


fuente
0

Enrutador UI . Fragmento de código para activar la barra de navegación.

HTML

<li ui-sref-active="is-active" ui-nested><a ui-sref="course">Courses</a>
</li> <li ui-sref-active="is-active" ui-nested><a ui-sref="blog">blog</a></li>

CSS

is-active{
      background-color: rgb(28,153,218);
}

Dentro de courseView.HTML

<button type="button" ui-sref="blog" class="btn btn-primary">Next</button>

Este botón está presente dentro de la Vista del curso que lo lleva a la siguiente Vista, es decir, al blog. y resalta la barra de navegación.

encuentre un ejemplo similar, una aplicación de enrutador ui angular de demostración: https://github.com/vineetsagar7/Angualr-UI-Router

sagar de vinagre
fuente
0

Mi código navegó de / productGroups a / productPartitions, que es la única forma de acceder a la vista "productPartitions".

Así que agregué un ancla oculta con ui-sref también configurado en "productPartitions" dentro del mismo elemento de lista que tiene ui-sref-active

<li ui-sref-active="active">
     <a ui-sref="productGroups">
     <i class="fa fa-magic"></i> Product groups </a>
     <a ui-sref="productPartitions" style="display:none;"></a>
</li>

Ahora el botón de navegación de grupos de productos permanece activo al acceder a cualquiera de las vistas

C Rudolph
fuente
0

Aquí lo que hice para lograr lo mismo. El estado principal es "app.message" y no se declara como abstracto.

Los estados secundarios son "app.message.draft", "app.message.all", "app.message.sent".

Mi enlace de navegación -

<a ui-sref-active="active-menu" ui-sref="app.message">Messages</a>

Defina las rutas / enlaces de sus hijos.

y actualizar en config-

$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
                if (toState.name === 'app.message') {
                    event.preventDefault();
                    $state.go('app.message.draft');
                    return;
                }
            });
Aditya Gupta
fuente