Angular UI路由器:导航到嵌套视图时,如何让父视图“活动”?

时间:2022-10-24 07:32:16

I'm working on a project that has implemented the UI router and it's using ui-sref-active="active" to add the active class to the navigation menu item when that item is the current route. However, when you navigate to a nested view within that view, the parent menu item is no longer active. See the following Plunker:

我正在开发一个已实现UI路由器的项目,并且当该项是当前路由时,它正在使用ui-sref-active =“active”将活动类添加到导航菜单项。但是,当您导航到该视图中的嵌套视图时,父菜单项不再处于活动状态。请参阅以下Plunker:

http://plnkr.co/edit/2CoEdS?p=preview

http://plnkr.co/edit/2CoEdS?p=preview

By default (or if you click on it) Route 1 is "active". When you click on "Show List," you will see that Route 1 is no longer active.

默认情况下(或者如果单击它),路由1处于“活动”状态。当您单击“显示列表”时,您将看到路由1不再处于活动状态。

Edit:

编辑:

The only difference between this example and my actual project is that the navigation menu in my actual project has its own controller and so does not use the same scope as the controller for "route1".

这个例子和我的实际项目之间的唯一区别是我的实际项目中的导航菜单有自己的控制器,所以不使用与“route1”的控制器相同的范围。

9 个解决方案

#1


60  

EDIT For updated ui-router 0.2.13:

编辑更新的ui-router 0.2.13:

ui-sref-active="active" now sets the 'active' class when the current state is the ui-sref's state or any child

ui-sref-active =“active”现在在当前状态为ui-sref状态或任何子节点时设置'active'类

ui-sref-active-eq="active" behaves as the previous iterations of ui-sref-active, and only sets the class for the exact state

ui-sref-active-eq =“active”表现为ui-sref-active的先前迭代,并且仅为精确状态设置类

Original Answer:

原答案:

See open ui-router issues: https://github.com/angular-ui/ui-router/issues/704 and 818

请参阅开放的ui-router问题:https://github.com/angular-ui/ui-router/issues/704和818

A general workaround people are suggesting is:

人们建议的一般解决方法是:

ng-class="{active:$state.includes('route1')}"

Of course, $state must be added to $scope. See updated plunk: http://plnkr.co/edit/KHLDJP?p=preview

当然,$ state必须添加到$ scope。请参阅更新的plunk:http://plnkr.co/edit/KHLDJP?p = preview

#2


8  

You are having a wrong understanding of ui-sref-active="active"

你对ui-sref-active =“active”有错误的理解

<li ui-sref-active="active"><a ui-sref="route1">Route 1</a></li>

This will show special css highlighting only when you are in state route1 (reference https://github.com/angular-ui/ui-router/wiki/Quick-Reference#wiki-ui-sref-active). This is the case when you click on route 1. But when you click on "Show list" you are no longer in route1. Rather you are in state "route1.list" . You can verify this by writing the following code. This is strictly for understanding how state works.

只有当您处于route1状态时,才会显示特殊的css突出显示(参考https://github.com/angular-ui/ui-router/wiki/Quick-Reference#wiki-ui-sref-active)。单击路径1时就是这种情况。但是当您单击“显示列表”时,您不再位于route1中。相反,你处于“route1.list”状态。您可以通过编写以下代码来验证这一点。这完全是为了理解国家的运作方式。

js

JS

inside controller

内部控制器

$rootScope.currentState = $state.$current.name //using rootScope so that you can access the variable anywhere inside html

inside html

在HTML内部

{{currentState}}

If you look closely at documentation of ui-sref-active, it not only looks at stateName but also stateParams, hence when you go to substate it no longer changes css. From the sourcecode it becomes clearer.

如果仔细观察ui-sref-active的文档,它不仅会查看stateName而且还会查看stateParams,因此当你转到它时它不再改变css。从源代码变得更加清晰。

 function update() {
        if ($state.$current.self === state && matchesParams()) {
          $element.addClass(activeClass);
        } else {
          $element.removeClass(activeClass);
        }// route1===route1.list will not be true.

to solve the problem, remember scope variables are inherited in nested views.

要解决此问题,请记住范围变量在嵌套视图中继承。

inside controller of route.

路线控制器内部。

$scope.route1Active = true;

in html

在HTML中

<li ng-class={active:route1Active}><a ui-sref="route1">Route 1</a></li>

#3


5  

Angular UI router now supports this natively. See commit https://github.com/angular-ui/ui-router/commit/bf163ad6ce176ce28792696c8302d7cdf5c05a01

Angular UI路由器现在支持此功能。请参阅提交https://github.com/angular-ui/ui-router/commit/bf163ad6ce176ce28792696c8302d7cdf5c05a01

#4


4  

My solution was to set:

我的解决方案是:

<li ng-class="{ 'active': state.current.name.indexOf('route1') != -1 }">

The state was already previously added to the controller's scope:

该状态之前已添加到控制器的范围内:

$scope.state = $state;

#5


2  

You do not need to do any thing in the controllers. Here is my example code:

你不需要在控制器中做任何事情。这是我的示例代码:

    <ul class="nav nav-pills nav-stacked" role="tablist">
        <li ui-sref-active="active"><a ui-sref="Booking.Step1" href="#/Booking/Step1">Step1</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step2" href="#/Booking/Step2" >Step2</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step3" href="#/Booking/Step3">Step3</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step4" href="#/Booking/Step4">Step4</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step5" href="#/Booking/Step5">Step5</a></li>
    </ul>

In route configuration:

在路线配置中:

$stateProvider.state('Booking', {
        abstract: true,
        url: '/Booking',
        templateUrl: "TourApp/Templates/Booking/SideMenu.html",
        controller: "SideMenuController"
    });

    $stateProvider.state('Booking.Step1', {
        url: "/Step1",
        views: {
            'content': {
                templateUrl: "TourApp/Templates/Booking/Step1.html",
                controller: "Step1Controller"
            }
        }
    });

    $stateProvider.state('Booking.Step2', {
        url: "/Step2",
        views: {
            'content': {
                templateUrl: "TourApp/Templates/Booking/Step2.html",
                controller: "Step2Controller"
            }
        }
    });

#6


1  

We already have a solution without any "hack" HERE

我们已经有了一个没有任何“黑客”的解决方案

That's the way to do:

这是做的方法:

HTML >

HTML>

 <li ui-sref-active="active" >
   <a href="#" class="submenu" ui-sref="bands">
       <i class="fa fa-location-arrow" aria-hidden="true"></i>
                     Bands
           <span class="fa fa-chevron-down"></span>
   </a>

   <ul class="nav child_menu">
        <li ui-sref-active="active">
            <a  ui-sref="bands.nirvana">
                 Nirvana   
            </a>
       </li>
       <li ui-sref-active="active">
            <a  ui-sref="bands.iron">
                Iron
            </a>
       </li>
       <li ui-sref-active="active">
            <a  ui-sref="bands.metalica">
                Metalica
            </a>
       </li>           
  </ul>

Our router config will be like this >

我们的路由器配置将是这样>

$stateProvider.state('bands', {
    abstract: true,
    url: '/bands',
    templateUrl: "myapp/categories/template.bands.html", //<ui-view></ui-view> 
    controller: "SomeController as vm"
}).state('bands.nirvana', {
    url: '/nirvana',
    templateUrl: "myapp/categories/band.nirvana.html",
    controller: "SomeController as vm"
}).state('bands.iron', {
    url: '/iron',
    templateUrl: "myapp/categories/band.iron.html",
    controller: "SomeController as vm"
}).state('bands.meatlica', {
    url: '/metalica',
    templateUrl: "myapp/categories/band.metalica.html",
    controller: "SomeController as vm"
})

#7


1  

I have come here 2 years later the question was asked but angular-ui-router has much proficient approach in solving this issue. It worked for nested states too.

2年后我来到这里问了这个问题但是angular-ui-router在解决这个问题上有很多熟练的方法。它也适用于嵌套状态。

<ul>
  <li ui-sref-active="active" class="item">
    <a ui-sref="home">Home</a>
  </li>
  <!-- ... -->
</ul>

When app navigates to home state, this is how resulting HTML will appear :

当应用导航到家庭状态时,这就是HTML显示的结果:

<ul>
  <li ui-sref-active="active" class="item active">
    <a ui-sref="home">Home</a>
  </li>
  <!-- ... -->
</ul>

ui-sref-active quick reference :

ui-sref-active快速参考:

A directive working alongside ui-sref to add classes to an element when the related ui-sref directive's state is active, and removing them when it is inactive. The primary use-case is to simplify the special appearance of navigation menus relying on ui-sref, by having the "active" state's menu button appear different, distinguishing it from the inactive menu items.

与ui-sref一起使用的指令,用于在相关ui-sref指令的状态处于活动状态时向元素添加类,并在其处于非活动状态时将其删除。主要用例是通过使“活动”状态的菜单按钮显示不同来简化依赖于ui-sref的导航菜单的特殊外观,从而将其与非活动菜单项区分开来。

Complete documentation.

完整的文档。

#8


1  

Now they have updated and the new way to do that is

现在他们已经更新了,新的方法就是这样做

 <a ui-sref-active="{'active': 'main.app.manage.**'}" ui-sref="main.app.manage.people.list"></a>

Below is the state file

以下是状态文件

 angular.module('manage.people', ['people.invite'])
  .config(['$stateProvider', function($stateProvider) {
    $stateProvider
      .state('main.app.manage.people', {
        url: '/people',
        abstract: true,
        cache: false,
        views: {
          'tabContent': {
            template: '<div ui-view="peopleContent"></div>',
            controller: 'peopleController'
          }
        }
      })
      .state('main.app.manage.people.list', {
        url: '/list',
        views: {
          'peopleContent': {
            templateUrl: '/internal/main/app/manage/people/views/people.html',
            controller: 'peopleListController'
          }
        }
      });

#9


0  

I hope this is what you have been looking for.Place the parent url in the list class ,now whenever you navigate to child class parent class will be active

我希望这是你一直在寻找的东西。将父网址放在列表类中,现在无论何时导航到子类,父类都将处于活动状态

Step 1: Add a Controller for your nav bar orin your existing controller where nav bar is included add the following

步骤1:为导航栏或现有控制器添加控制器,其中包含导航栏添加以下内容

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

}]);

Step2: In your nav bar

第2步:在导航栏中

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

Thats it.

而已。

#1


60  

EDIT For updated ui-router 0.2.13:

编辑更新的ui-router 0.2.13:

ui-sref-active="active" now sets the 'active' class when the current state is the ui-sref's state or any child

ui-sref-active =“active”现在在当前状态为ui-sref状态或任何子节点时设置'active'类

ui-sref-active-eq="active" behaves as the previous iterations of ui-sref-active, and only sets the class for the exact state

ui-sref-active-eq =“active”表现为ui-sref-active的先前迭代,并且仅为精确状态设置类

Original Answer:

原答案:

See open ui-router issues: https://github.com/angular-ui/ui-router/issues/704 and 818

请参阅开放的ui-router问题:https://github.com/angular-ui/ui-router/issues/704和818

A general workaround people are suggesting is:

人们建议的一般解决方法是:

ng-class="{active:$state.includes('route1')}"

Of course, $state must be added to $scope. See updated plunk: http://plnkr.co/edit/KHLDJP?p=preview

当然,$ state必须添加到$ scope。请参阅更新的plunk:http://plnkr.co/edit/KHLDJP?p = preview

#2


8  

You are having a wrong understanding of ui-sref-active="active"

你对ui-sref-active =“active”有错误的理解

<li ui-sref-active="active"><a ui-sref="route1">Route 1</a></li>

This will show special css highlighting only when you are in state route1 (reference https://github.com/angular-ui/ui-router/wiki/Quick-Reference#wiki-ui-sref-active). This is the case when you click on route 1. But when you click on "Show list" you are no longer in route1. Rather you are in state "route1.list" . You can verify this by writing the following code. This is strictly for understanding how state works.

只有当您处于route1状态时,才会显示特殊的css突出显示(参考https://github.com/angular-ui/ui-router/wiki/Quick-Reference#wiki-ui-sref-active)。单击路径1时就是这种情况。但是当您单击“显示列表”时,您不再位于route1中。相反,你处于“route1.list”状态。您可以通过编写以下代码来验证这一点。这完全是为了理解国家的运作方式。

js

JS

inside controller

内部控制器

$rootScope.currentState = $state.$current.name //using rootScope so that you can access the variable anywhere inside html

inside html

在HTML内部

{{currentState}}

If you look closely at documentation of ui-sref-active, it not only looks at stateName but also stateParams, hence when you go to substate it no longer changes css. From the sourcecode it becomes clearer.

如果仔细观察ui-sref-active的文档,它不仅会查看stateName而且还会查看stateParams,因此当你转到它时它不再改变css。从源代码变得更加清晰。

 function update() {
        if ($state.$current.self === state && matchesParams()) {
          $element.addClass(activeClass);
        } else {
          $element.removeClass(activeClass);
        }// route1===route1.list will not be true.

to solve the problem, remember scope variables are inherited in nested views.

要解决此问题,请记住范围变量在嵌套视图中继承。

inside controller of route.

路线控制器内部。

$scope.route1Active = true;

in html

在HTML中

<li ng-class={active:route1Active}><a ui-sref="route1">Route 1</a></li>

#3


5  

Angular UI router now supports this natively. See commit https://github.com/angular-ui/ui-router/commit/bf163ad6ce176ce28792696c8302d7cdf5c05a01

Angular UI路由器现在支持此功能。请参阅提交https://github.com/angular-ui/ui-router/commit/bf163ad6ce176ce28792696c8302d7cdf5c05a01

#4


4  

My solution was to set:

我的解决方案是:

<li ng-class="{ 'active': state.current.name.indexOf('route1') != -1 }">

The state was already previously added to the controller's scope:

该状态之前已添加到控制器的范围内:

$scope.state = $state;

#5


2  

You do not need to do any thing in the controllers. Here is my example code:

你不需要在控制器中做任何事情。这是我的示例代码:

    <ul class="nav nav-pills nav-stacked" role="tablist">
        <li ui-sref-active="active"><a ui-sref="Booking.Step1" href="#/Booking/Step1">Step1</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step2" href="#/Booking/Step2" >Step2</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step3" href="#/Booking/Step3">Step3</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step4" href="#/Booking/Step4">Step4</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step5" href="#/Booking/Step5">Step5</a></li>
    </ul>

In route configuration:

在路线配置中:

$stateProvider.state('Booking', {
        abstract: true,
        url: '/Booking',
        templateUrl: "TourApp/Templates/Booking/SideMenu.html",
        controller: "SideMenuController"
    });

    $stateProvider.state('Booking.Step1', {
        url: "/Step1",
        views: {
            'content': {
                templateUrl: "TourApp/Templates/Booking/Step1.html",
                controller: "Step1Controller"
            }
        }
    });

    $stateProvider.state('Booking.Step2', {
        url: "/Step2",
        views: {
            'content': {
                templateUrl: "TourApp/Templates/Booking/Step2.html",
                controller: "Step2Controller"
            }
        }
    });

#6


1  

We already have a solution without any "hack" HERE

我们已经有了一个没有任何“黑客”的解决方案

That's the way to do:

这是做的方法:

HTML >

HTML>

 <li ui-sref-active="active" >
   <a href="#" class="submenu" ui-sref="bands">
       <i class="fa fa-location-arrow" aria-hidden="true"></i>
                     Bands
           <span class="fa fa-chevron-down"></span>
   </a>

   <ul class="nav child_menu">
        <li ui-sref-active="active">
            <a  ui-sref="bands.nirvana">
                 Nirvana   
            </a>
       </li>
       <li ui-sref-active="active">
            <a  ui-sref="bands.iron">
                Iron
            </a>
       </li>
       <li ui-sref-active="active">
            <a  ui-sref="bands.metalica">
                Metalica
            </a>
       </li>           
  </ul>

Our router config will be like this >

我们的路由器配置将是这样>

$stateProvider.state('bands', {
    abstract: true,
    url: '/bands',
    templateUrl: "myapp/categories/template.bands.html", //<ui-view></ui-view> 
    controller: "SomeController as vm"
}).state('bands.nirvana', {
    url: '/nirvana',
    templateUrl: "myapp/categories/band.nirvana.html",
    controller: "SomeController as vm"
}).state('bands.iron', {
    url: '/iron',
    templateUrl: "myapp/categories/band.iron.html",
    controller: "SomeController as vm"
}).state('bands.meatlica', {
    url: '/metalica',
    templateUrl: "myapp/categories/band.metalica.html",
    controller: "SomeController as vm"
})

#7


1  

I have come here 2 years later the question was asked but angular-ui-router has much proficient approach in solving this issue. It worked for nested states too.

2年后我来到这里问了这个问题但是angular-ui-router在解决这个问题上有很多熟练的方法。它也适用于嵌套状态。

<ul>
  <li ui-sref-active="active" class="item">
    <a ui-sref="home">Home</a>
  </li>
  <!-- ... -->
</ul>

When app navigates to home state, this is how resulting HTML will appear :

当应用导航到家庭状态时,这就是HTML显示的结果:

<ul>
  <li ui-sref-active="active" class="item active">
    <a ui-sref="home">Home</a>
  </li>
  <!-- ... -->
</ul>

ui-sref-active quick reference :

ui-sref-active快速参考:

A directive working alongside ui-sref to add classes to an element when the related ui-sref directive's state is active, and removing them when it is inactive. The primary use-case is to simplify the special appearance of navigation menus relying on ui-sref, by having the "active" state's menu button appear different, distinguishing it from the inactive menu items.

与ui-sref一起使用的指令,用于在相关ui-sref指令的状态处于活动状态时向元素添加类,并在其处于非活动状态时将其删除。主要用例是通过使“活动”状态的菜单按钮显示不同来简化依赖于ui-sref的导航菜单的特殊外观,从而将其与非活动菜单项区分开来。

Complete documentation.

完整的文档。

#8


1  

Now they have updated and the new way to do that is

现在他们已经更新了,新的方法就是这样做

 <a ui-sref-active="{'active': 'main.app.manage.**'}" ui-sref="main.app.manage.people.list"></a>

Below is the state file

以下是状态文件

 angular.module('manage.people', ['people.invite'])
  .config(['$stateProvider', function($stateProvider) {
    $stateProvider
      .state('main.app.manage.people', {
        url: '/people',
        abstract: true,
        cache: false,
        views: {
          'tabContent': {
            template: '<div ui-view="peopleContent"></div>',
            controller: 'peopleController'
          }
        }
      })
      .state('main.app.manage.people.list', {
        url: '/list',
        views: {
          'peopleContent': {
            templateUrl: '/internal/main/app/manage/people/views/people.html',
            controller: 'peopleListController'
          }
        }
      });

#9


0  

I hope this is what you have been looking for.Place the parent url in the list class ,now whenever you navigate to child class parent class will be active

我希望这是你一直在寻找的东西。将父网址放在列表类中,现在无论何时导航到子类,父类都将处于活动状态

Step 1: Add a Controller for your nav bar orin your existing controller where nav bar is included add the following

步骤1:为导航栏或现有控制器添加控制器,其中包含导航栏添加以下内容

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

}]);

Step2: In your nav bar

第2步:在导航栏中

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

Thats it.

而已。