在视图和$ routing中干掉逻辑

时间:2015-08-20 17:55:14

标签: javascript angularjs

我还在学习Angular并开始创建一个简单的网站。我在视图中有路由和一些逻辑,当网址在该页面上时,菜单项上有一个活动类。我开始看到的问题是,如果我将URL更改为/ to / home,我必须在路由和视图中更新它,还要检查逻辑是否应该是活动的。

我想知道是否有更好的方法让它干涸?

我的app.js文件如下所示:

    angular.module('simpleApp', ['ngRoute'])
  .config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/home/index.html'
      })
      .when('/about', {
        templateUrl: 'views/about/index.html',
        controller: 'AboutController',
        controllerAs: 'aboutCtrl'
      })
      .when('/services', {
        templateUrl: 'views/services/index.html',
        controller: 'ServicesController',
        controllerAs: 'servicesCtrl'
      })
      .when('/contact', {
        templateUrl: 'views/contact/index.html',
        controller: 'ContactController',
        controllerAs: 'contactCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  }]);

我的index.html的部分视图如下所示:

<nav class="navbar navbar-inverse" ng-controller="NavController as navCtrl">
          <div class="container-fluid">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header">
              <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
              </button>
              <a class="navbar-brand" href="/#/">SimpleApp</a>
            </div>
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
              <ul class="nav navbar-nav">
                <li ng-class="{ 'active': navCtrl.isActive('/')}">
                  <a href="/#/">Home</a>
                </li>
                <li ng-class="{ 'active': navCtrl.isActive('/about')}">
                  <a href="/#/about">About</a>
                </li>
                <li ng-class="{ 'active': navCtrl.isActive('/services')}">
                  <a href="/#/services">Services</a>
                </li>
                <li ng-class="{ 'active': navCtrl.isActive('/contact')}">
                  <a href="/#/contact">Contact Us</a>
                </li>
              </ul>
            </div>
          </div>
        </nav>

你可以看到我在导航控制器上调用isActive方法,但我必须始终确保传入的URL是正确的。

这是我的导航控制器:

    angular.module('simpleApp')
  .controller('NavController', function($scope, $location) {
    this.isActive = function (url) {
      return url === $location.path();
    };
  });

5 个答案:

答案 0 :(得分:1)

如果您不想重复自己,为什么不使用ng-repeat

<ul class="nav navbar-nav">
  <li ng-repeat="item in navbarLinks" ng-class="{ 'active': navCtrl.isActive(item.link)}">
     <a href="/#{{item.link}}">{{item.text}}</a>
  </li>
</ul>

我的意思是,不必重复自己就是它存在的原因。所以你不要重复自己。 ng-repeat实际上非常适合那些你不想重复的情况。如果你想避免重复自己,我建议你使用它。而“我”是指ng-repeat。为了避免重复。

答案 1 :(得分:0)

查看ng-class指令。

https://docs.angularjs.org/api/ng/directive/ngClass

基本上,您在菜单项上有一个ng-class引用,它使用表达式部分将菜单项与活动项进行比较,然后当该表达式求值为true时,该类将应用于该项。

答案 2 :(得分:0)

这是自定义指令的好地方。该指令可以像上面那样呈现html,但是文档中的实际html看起来像<myNav url='about'>

答案 3 :(得分:0)

我终于弄明白了我需要从可能的重复问题中做些什么,但稍微改变它以使用&#39; /&#39;网址。

这是我的index.html

<!DOCTYPE html>
<html>
<head>
  <title>Simple Angular App</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
  <link rel="stylesheet" type="text/css" href="css/styles.css">
</head>
  <body ng-app="simpleApp">
    <header>
      <div class="container">
        <nav class="navbar navbar-inverse">
          <div class="container-fluid">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header">
              <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
              </button>
              <a class="navbar-brand" href="/#/">SimpleApp</a>
            </div>
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
              <ul class="nav navbar-nav">
                <li>
                  <a href="#/" detect-active-tab="1">Home</a>
                </li>
                <li>
                  <a href="#/about" detect-active-tab="1">About</a>
                </li>
                <li>
                  <a href="#/services" detect-active-tab="1">Services</a>
                </li>
                <li>
                  <a href="#/contact" detect-active-tab="1">Contact Us</a>
                </li>
              </ul>
            </div>
          </div>
        </nav>
      </div>
    </header>
    <main>
      <div class="container">
        <div class="row">
          <div ng-view></div>
        </div>
      </div>
    </main>
    <footer>
      <div class="container">
        <div class="row">
          <div class="col-xs-12">
            <p class="footer-text">First attempt at an AngularJs site</p>
          </div>
        </div>
      </div>
    </div>
  </footer>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
    <script src="https://code.angularjs.org/1.4.4/angular-route.min.js"></script>

    <script src="js/app.js"></script>

    <script src="js/directives/shared/navdirective.js"></script>

    <script src="js/controllers/contact/ContactController.js"></script>
    <script src="js/controllers/about/AboutController.js"></script>
    <script src="js/controllers/services/ServicesController.js"></script>
  </body>
</html>

这是我的app.js:

angular.module('simpleApp', ['ngRoute'])
  .config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/home/index.html'
      })
      .when('/about', {
        templateUrl: 'views/about/index.html',
        controller: 'AboutController',
        controllerAs: 'aboutCtrl'
      })
      .when('/services', {
        templateUrl: 'views/services/index.html',
        controller: 'ServicesController',
        controllerAs: 'servicesCtrl'
      })
      .when('/contact', {
        templateUrl: 'views/contact/index.html',
        controller: 'ContactController',
        controllerAs: 'contactCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });

      // if(window.history && window.history.pushState) {
      //   $locationProvider.html5Mode({
      //     enabled: true,
      //     requireBase: false
      //   });
      // }
  }]);

这是我的导航文件:

angular.module('simpleApp')
  .directive('detectActiveTab', function ($location) {
    return {
      restrict: 'A',
      link: function postLink(scope, element, attrs) {
        scope.$on("$routeChangeSuccess", function (event, current, previous) {
            // This var grabs the tab-level off the attribute, or defaults to 1
            var pathLevel = attrs.detectActiveTab || 1;

            if($location.path() === '/') {
              var pathToCheck = $location.path() ||
                  "current $location.path doesn't reach this level";
              var tabLink = attrs.href.split('#')[pathLevel] ||
                  "href doesn't include this level";
            } else {
              var pathToCheck = $location.path().split('/')[pathLevel] ||
                  "current $location.path doesn't reach this level";
                  // This var finds grabs the same level of the href attribute
              var tabLink = attrs.href.split('/')[pathLevel] ||
                  "href doesn't include this level";
            }

            if (pathToCheck === tabLink) {
              element.parent('li').addClass('active');
            }
            else {
              element.parent('li').removeClass('active');
            }
        });
      }
    };
  });

要使用此功能,我将detect-active-tab="1"添加到我的标签中,然后将该指令包含在我的index.html中

我也看过ui路由器并且它使事情变得更简单,因为路由的设置与ngRoute的设置方式非常相似,但你要做的只是将ui-sref="/services"添加到我的链接和{{ 1}}对我来说,这对我来说是活跃的状态,非常好。

答案 4 :(得分:0)

虽然我的第一个答案确实解决了我原来的问题。它给了我其他问题,它非常复杂,难以维护。我决定切换到UI路由器,这使事情变得更容易。

我的app.js文件现在看起来像这样:

angular.module('simpleApp', ['ui.router'])
  .config(function ($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise('/');

    $stateProvider
      .state('/', {
        url: '/',
        templateUrl: 'views/home/index.html'
      })
      .state('/about', {
        url: '/about',
        templateUrl: 'views/about/index.html',
        controller: 'AboutController',
        controllerAs: 'aboutCtrl'
      })
      .state('/services', {
        url: '/services',
        templateUrl: 'views/services/index.html',
        controller: 'ServicesController',
        controllerAs: 'servicesCtrl'
      })
      .state('/contact', {
        url: '/contact',
        templateUrl: 'views/contact/index.html',
        controller: 'ContactController',
        controllerAs: 'contactCtrl'
      });
  });

我的html看起来像这样:

    <!DOCTYPE html>
<html>
<head>
  <title>Simple Angular App</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
  <link rel="stylesheet" type="text/css" href="css/styles.css">
</head>
  <body ng-app="simpleApp">
    <header>
      <div class="container">
        <nav class="navbar navbar-inverse">
          <div class="container-fluid">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header">
              <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
              </button>
              <a class="navbar-brand" href="/#/">SimpleApp</a>
            </div>
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
              <ul class="nav navbar-nav">
                <li ui-sref-active="active">
                  <a ui-sref="/">Home</a>
                </li>
                <li ui-sref-active="active">
                  <a ui-sref="/about">About</a>
                </li>
                <li ui-sref-active="active">
                  <a ui-sref="/services">Services</a>
                </li>
                <li ui-sref-active="active">
                  <a ui-sref="/contact">Contact Us</a>
                </li>
              </ul>
            </div>
          </div>
        </nav>
      </div>
    </header>
    <main>
      <div class="container">
        <div class="row">
          <div ui-view></div>
        </div>
      </div>
    </main>
    <footer>
      <div class="container">
        <div class="row">
          <div class="col-xs-12">
            <p class="footer-text">First attempt at an AngularJs site</p>
          </div>
        </div>
      </div>
    </div>
  </footer>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
    <script src="js/lib/angular-ui-router.min.js"></script>

    <script src="js/app.js"></script>

    <script src="js/controllers/contact/ContactController.js"></script>
    <script src="js/controllers/about/AboutController.js"></script>
    <script src="js/controllers/services/ServicesController.js"></script>
  </body>
</html>

我所要做的就是在index.html中添加对UI路由器的引用,并根据UI路由器的文档更改配置。然后将ui-srefui-sref-active="active"添加到li中以使其处于活动状态,UI路由器的魔力完成其余部分。