Angular UI 路由器:导航到嵌套视图时如何使父视图处于“活动”状态?
-
21-12-2019 - |
题
我正在开发一个已实现 UI 路由器的项目,它正在使用 ui-sref-active="active"
当该项目是当前路线时,将活动类添加到导航菜单项。但是,当您导航到该视图中的嵌套视图时,父菜单项不再处于活动状态。请参阅以下 Plunker:
http://plnkr.co/edit/2CoEdS?p=preview
默认情况下(或者如果您单击它)路线 1 处于“活动”状态。当您单击“显示列表”时,您将看到路线 1 不再处于活动状态。
编辑:
此示例与我的实际项目之间的唯一区别是,我的实际项目中的导航菜单有自己的控制器,因此不使用与“route1”控制器相同的范围。
解决方案
编辑更新的 ui-router 0.2.13:
ui-sref-active="active"
现在当当前状态是 ui-sref 的状态时设置“活动”类 或任何孩子
ui-sref-active-eq="active"
行为与 ui-sref-active 的先前迭代相同,并且仅设置确切状态的类
原答案:
查看开放式 ui-router 问题:https://github.com/angular-ui/ui-router/issues/704 和 818
人们建议的一般解决方法是:
ng-class="{active:$state.includes('route1')}"
当然,$state必须添加到$scope中。请参阅更新的 plunk: http://plnkr.co/edit/KHLDJP?p=preview
其他提示
您对 ui-sref-active="active" 的理解有误
<li ui-sref-active="active"><a ui-sref="route1">Route 1</a></li>
仅当您处于状态route1时,这才会显示特殊的CSS突出显示(参考 https://github.com/angular-ui/ui-router/wiki/Quick-Reference#wiki-ui-sref-active)。当您点击路线 1 时就会出现这种情况。但是当您单击“显示列表”时,您不再位于路线 1 中。相反,您处于状态 "route1.list" 。您可以通过编写以下代码来验证这一点。这严格是为了理解状态如何运作。
js
内部控制器
$rootScope.currentState = $state.$current.name //using rootScope so that you can access the variable anywhere inside html
html 里面
{{currentState}}
如果您仔细查看 ui-sref-active 的文档,它不仅会查看 stateName,还会查看 stateParams,因此当您转到 substate 时,它不再更改 css。从源代码来看就更清楚了。
function update() {
if ($state.$current.self === state && matchesParams()) {
$element.addClass(activeClass);
} else {
$element.removeClass(activeClass);
}// route1===route1.list will not be true.
要解决这个问题,请记住范围变量是在嵌套视图中继承的。
路线控制器内部。
$scope.route1Active = true;
在 HTML 中
<li ng-class={active:route1Active}><a ui-sref="route1">Route 1</a></li>
Angular UI 路由器现在原生支持此功能。查看提交 https://github.com/angular-ui/ui-router/commit/bf163ad6ce176ce28792696c8302d7cdf5c05a01
我的解决方案是设置:
<li ng-class="{ 'active': state.current.name.indexOf('route1') != -1 }">
该状态之前已添加到控制器的范围中:
$scope.state = $state;
您不需要在控制器中执行任何操作。这是我的示例代码:
<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>
在路由配置中:
$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"
}
}
});
现在他们已经更新了,新的方法是
<a ui-sref-active="{'active': 'main.app.manage.**'}" ui-sref="main.app.manage.people.list"></a>
下面是状态文件
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'
}
}
});
我们已经有了一个没有任何“黑客”的解决方案 这里
这就是这样做的方法:
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>
我们的路由器配置将是这样的>
$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"
})
两年后我来到这里,有人问了这个问题,但是 angular-ui-router
在解决这个问题上有很多熟练的方法。它也适用于嵌套状态。
<ul>
<li ui-sref-active="active" class="item">
<a ui-sref="home">Home</a>
</li>
<!-- ... -->
</ul>
当应用程序导航到 home
状态,这就是生成的 HTML 的显示方式:
<ul>
<li ui-sref-active="active" class="item active">
<a ui-sref="home">Home</a>
</li>
<!-- ... -->
</ul>
ui-sref-active 快速参考:
当相关的UI-SREF指令的状态处于活动状态时,与UI-SREF一起工作的指令将类添加到元素中,并在不活动时将其删除。主要用例是通过使“ Active”状态菜单按钮看起来不同,从而简化依赖UI-SREF的导航菜单的特殊外观,从而将其与不活动的菜单项区分开来。
我希望这就是您一直在寻找的。将父 url 放在列表类中,现在每当您导航到子类时父类都会处于活动状态
步骤1:为您的导航栏添加一个控制器,或者在包含导航栏的现有控制器中添加以下内容
app.controller('navCtrl', ['$scope', '$location', function($scope, $location) {
$scope.isActive = function(destination) {
return destination === $location.path();
}
}]);
第2步:在您的导航栏中
<li ng-class="{active: isActive('/home')}"><a ui-sref="app.home">Browse Journal</a></li>
就是这样。