【问题标题】:AngularJS Changing <body> class using global variableAngularJS 使用全局变量更改 <body> 类
【发布时间】:2014-01-23 11:51:30
【问题描述】:

我刚刚创建了一个 angularJS 应用程序。

这是我的 index.html

<html ng-app="MyApp">
  <head>
    <!-- CSS files import -->
  </head>
  <body class="{{bodylayout}}">
    <div ng-view></div>
  </body>
  <--! JS imports 
   aungular.js
   app.js
   login.js
   register.js
   -->
</html>

app.js

'use strict';
//Define Routing for app
angular.module('myApp', []).config(['$routeProvider', '$locationProvider',
  function($routeProvider,$locationProvider) {
    $routeProvider
    .when('/login', {
        templateUrl: 'login.html',
        controller: 'LoginController'
    })
    .when('/register', {
        templateUrl: 'register.html',
        controller: 'RegisterController'
      })
    .when('/forgotPassword', {
        templateUrl: 'forgotpassword.html',
        controller: 'forgotController'
      })
   .when('/home', {
       templateUrl: 'views/home.html',
    })
    .otherwise({
       redirectTo: '/login'
    });
//    $locationProvider.html5Mode(true); //Remove the '#' from URL.
}]);

我有 login.html、register.html 和 forgotpassword.html、home.html。每个都有单独的控制器在单独的文件中。 login.js、register.js、forgot.js、home.js。

login.js

'use strict';

angular.module('myApp').controller('LoginController', function($scope, $location, $window) {
    $scope.user = {};
    $scope.loginUser=function()
    {
        var username=$scope.user.name;
        var password=$scope.user.password;
        if(username=="admin" && password=="admin123")
        {
            $location.path( "/home" );  
        }
        else
        {
            $scope.message="Error";
            $scope.messagecolor="alert alert-danger";
        }
    }
});

同样,我在其他控制器中也有 post 方法。

我想要的是,当视图是登录或注册或忘记密码时,正文类应该是"login-layout"。所以在正文中我放了class="{{bodylayout}}"。我知道使用全局变量,可以设置值。但我不知道如何。

app.js 我试过这个

angular.module('myApp').factory("myService", function(){

      return {
        sharedObject: { data: 'login-layout' }
      }; 

    });

但是不知道怎么用。

【问题讨论】:

    标签: javascript jquery html angularjs global-variables


    【解决方案1】:

    尝试使用 $rootScope:

    $rootScope.bodyClass = 'login-layout';
    
    <body class="{{$root.bodyClass}}">
    

    您可以在单个控制器中处理此问题,或者在您的 app.js 中通过侦听 routeChangeSuccess 来处理:

    $rootScope.$on('$routeChangeSuccess', function (event, currentRoute) {
        switch(currentRoute.templateUrl) {
            case 'login.html':
            case 'register.html':
            case 'forgotpassword.html':
                $rootScope.bodyClass = 'login-layout';
                break;
            default:
                $rootScope.bodyClass = '';
                break;
        }
    });
    

    【讨论】:

    • 在哪里使用?在哪个js文件中?
    • 更干净的解决方案,谢谢!虽然我还是会去使用服务
    • 因为它在$rootScope 中,您可以简单地使用&lt;body class="{{bodyClass}}"&gt; 在您的视图中引用它。
    【解决方案2】:

    您可以通过两种方式创建全局变量

    使用$rootScope,您可以在LoginController 控制器中执行类似操作

    angular.module('myApp').controller('LoginController', function($scope, $location, $window, $rootScope) {
       $scope.user = {};
       $rootScope.bodylayout = 'login-layout';
    
       //others code 
    }
    

    使用service

    angular.module('myApp').factory("myService", function(){
    
          return {
            sharedObject: { data: 'login-layout' }
          }; 
    
    });
    

    在您的控制器中使用此服务

    angular.module('myApp').controller('LoginController', function($scope, $location, $window, myService) {
           $scope.user = {};
           $rootScope.bodylayout = myService.sharedObject.data; // get data from service
    
           //others code 
        }
    

    HTML 的样子

    <body class="{{bodylayout}}">
    

    注意在这种情况下,您需要在每个控制器中设置bodylayout,否则它会使用旧值

    【讨论】:

    • 谢谢。如果是其他控制器,如何设置其他或空白?
    • 在其他控制器中可以设置$rootScope.bodylayout = '' or $rootScope.bodylayout = 'other value'
    • 有服务,怎么样?因为我们使用$rootScope.bodylayout = myService.sharedObject.data; 没有从控制器传递任何值。我还想更改每个控制器中的页面标题。
    • 在您的服务中设置不同的值,例如sharedObject: { data: 'login-layout', data2: 'another-layout' },然后在另一个控制器中使用,例如$rootScope.bodylayout = myService.sharedObject.data2
    • 无法从控制器设置?在服务中创建一个方法并从控制器传递值?
    【解决方案3】:

    您可以创建一个 &lt;body&gt; 指令,其中包含可以在整个应用程序中触发的添加和删除类事件。

    angular.module('myApp').directive('body', [function(){
      return {
        restrict: 'E',
        link: function(scope, element, attrs) {
          scope.$on('body:class:add', function(e, name){
            element.addClass(name);
          };
          scope.$on('body:class:remove', function(e, name){
            element.removeClass(name);
          };
          return;
        }
      };
    }]);
    

    在您的app.js config 块中,您可以使用$emit&lt;body&gt; class 设置为您想要的任何内容

    ## Add class
    $rootScope.$emit('body:class:add', 'login-layout')
    
    ## Remove class
    $rootScope.$emit('body:class:remove', 'login-layout')
    

    它只是简单地使用 angular jqLit​​e addClass()removeClass() 并且不需要您通过使用指令 link 函数来利用 $element,该指令已经对元素具有 dom 访问权限。

    即使没有$rootScope,您也可以在控制器中使用$scope.$emit('body:class:add', name) 调用它。

    【讨论】:

      【解决方案4】:

      我不太确定建议的答案是否适用于 Angular 1.4x,但我认为我有一个更简单的解决方案。

      您可以像这样轻松地将 activeTab 属性添加到您的路线中:

      .when('/register', {
              templateUrl: 'register.html',
              controller: 'RegisterController',
              activeTab: 'register'
            })
      

      然后在你的 Controller 中添加 $route 对象到你的 $scope:

      .controller('RegisterController', ['$scope', '$route', function($scope, $route){
           $scope.$route = $route;
      }])
      

      在你的 body 标签上使用 ng-class:

      <body ng-class="{'register-class' : $route.current.activeTab == 'register' }">
      </body>
      

      通过这种方式,您可以在更改路线时在 body 标签上动态设置一个类。希望这对某人有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-09
        • 1970-01-01
        相关资源
        最近更新 更多