Active Class Based On Selected Menu

2019-09-06 18:44发布

问题:

I'm learning angular and try to create a navbar menu and set 'active' class based on current page.

index.html

<html lang="en" data-ng-app="Afe" class="no-js">
   <head>
        <!-- code omitted.. -->
   </head>
   <body>
        <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
            <div class="container-fluid">
                <div class="collapse navbar-collapse">
                    <ul class="nav navbar-nav" data-ng-init="activeMenu='AfeCoverPage'">
                        <li data-ng-class="{active: activeMenu=='AfeCoverPage'}" data-ng-click="activeMenu='AfeCoverPage'"><a href="#/AfeCoverPage">AFE Cover Page</a></li>
                        <li data-ng-class="{active: activeMenu=='AfeCostEstimate'}" data-ng-click="activeMenu='AfeCostEstimate'"><a href="#/AfeCostEstimate">AFE Cost Estimate</a></li>
                        <li data-ng-class="{active: activeMenu=='AfeVariance'}" data-ng-click="activeMenu='AfeVariance'"><a href="#/AfeVariance">AFE Variance</a></li>
                    </ul>
                </div>
            </div>
        </nav>
        <div data-ng-view=""></div>

        <!-- code omitted.. -->
        <script src="js/app.js"></script>
        <script src="js/controllers.js"></script>
   </body>
</html>

app.js

angular.module('Afe', ['ngRoute', 'Afe.controllers']).
    config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/AfeCoverPage', { templateUrl: 'partials/AfeCoverPage.html', controller: 'AfeCoverPageCtrl' });
        $routeProvider.when('/AfeCostEstimate', { templateUrl: 'partials/AfeCostEstimate.html', controller: 'AfeCostEstimateCtrl' });
        $routeProvider.when('/AfeVariance', { templateUrl: 'partials/AfeVariance.html', controller: 'AfeVarianceCtrl' });
        $routeProvider.otherwise({ redirectTo: '/AfeCoverPage' });
    }]);

controllers.js

angular.module('Afe.controllers', []).
    controller('GlobalCtrl', ['$scope', function ($scope) {
    }]).
    controller('AfeCoverPageCtrl', ['$scope', function ($scope) {
    }]).
    controller('AfeCostEstimateCtrl', ['$scope', function ($scope) {
    }]).
    controller('AfeVarianceCtrl', ['$scope', function ($scope) {
    }]);

Currently it's working, when Afe Cover Page menu is clicked, the <li> element will have 'active' class, but I'm not sure whether using ng-click is the right way. The code seems to be duplicated. Could anyone show me the best way to do it?

回答1:

You could just use the $location service and a function in your ng-class directive that returns a bool if it matches the current path.

<div class="collapse navbar-collapse" ng-controller="MenuController">
    <ul class="nav navbar-nav">
        <li data-ng-class="{active: isActive('/AfeCoverPage')}"><a href="#/AfeCoverPage">AFE Cover Page</a></li>
        <li data-ng-class="{active: isActive('/AfeCostEstimate')}"><a href="#/AfeCostEstimate">AFE Cost Estimate</a></li>
        <li data-ng-class="{active: isActive('/AfeVariance')}"><a href="#/AfeVariance">AFE Variance</a></li>
    </ul>
</div>

With a controller:

.controller('MenuController', function ($scope, $location) {
    $scope.isActive = function (path) {
       return $location.path() === path;
    }
});