Изменение тела цвет фона с AngularJS

Я хочу иметь возможность изменить цвет фона <body> в зависимости от текущего пути.

Я попытался сделать это, проверив $location.путь() всякий раз, когда путь был изменен, а затем с помощью ng-style директива для изменения цвета фона, но это похоже на хак (и не сработало).

что было бы более развязанным способом достичь этого?

вот код, который я написал, Если кто-то хочет видеть его.

app.controller('backgroundCtrl', ['$rootScope', '$scope', '$route', '$location', function($rootScope, $scope, $route, $location){
  $rootScope.$on('$routeChangeStart', function(){

    if ($location.path() == '/'){
      $scope.backgroundStyle = {background: '#ffffff'};
    } else {
      $scope.backgroundStyle = {background: '#000000'};
    }

  });
}]);

3 ответов


чтобы отделить такое динамическое изменение стиля, данных, контента и т. д., часто целесообразно создать другой угловой модуль, содержащий интерфейс (пользовательский поставщик), который может предоставить вам доступ к этим изменениям до и после уровня конфигурации. Вот это plunker чтобы дать представление о том, что я буду обсуждать ниже.

для этого ответа я создал небольшой модуль (route-data.js) с provider, RouteData, который предоставляет две функции конфигурации:

applyConfig() - назначает параметры для доступа в службе RouteData. hookToRootScope() - крючки службы RouteData в $rootScope следовательно, сделать его доступным для всех дочерних областей, которые будут созданы и всего приложения.

поставщик RouteData имеет RouteData() сервис, который предоставляет доступ к методам, которые устанавливает и получает RouteData настройки, которые будут предоставлены в $routeProvider конфигурации.

(если вы не знакомы с поставщиками и услуги, подробнее об этом здесь)

(если вы не знакомы с config() и run() методы, вы можете прочитать больше в здесь)

маршрут-данных.js

angular.module('RouteData', []).

provider('RouteData', function () {
  var settings = {};
  var hookToRootScope = false;

  this.applyConfig = function(newSettings) {
    settings = newSettings;
  };

  this.hookToRootScope = function(enableRootScopeHook) {
    hookToRootScope = enableRootScopeHook;
  };

  function RouteData() {

    this.set = function(index, value) {
      settings[index] = value;
    };

    this.get = function(index) {
      if(settings.hasOwnProperty(index)) {
        return settings[index];
      } else {
        console.log('RouteData: Attempt to access a propery that has not been set');
      }
    };

    this.isHookedToRootSope = function() {
      return hookToRootScope;
    };
  }

  this.$get = function() {
      return new RouteData();
  };
}).

run(['$location', '$rootScope', 'RouteData', function($location, $rootScope, RouteData) {
  if(RouteData.isHookedToRootSope()) {
    $rootScope.RouteData = RouteData;
  }

  $rootScope.$on('$routeChangeStart', function(event, current, previous) {
    var route = current.$$route;
    if(typeof(route) !== 'undefined' && typeof(route['RouteData']) !== 'undefined') {
      var data = route['RouteData'];
      for(var index in data)
        RouteData.set(index, data[index]);
    } 
  });
}]);

сценарий ниже показывает, как использовать модуль RouteData выше, путем инъекции RouteDataProvider на уровне конфигурации и применять конфигурации по умолчанию, такие как bodyStyle via RouteDataProvider.applyConfig(), вы можете также добавить дополнительные параметры перед приложение полностью работает. Подключите его в $rootScope, установив RouteDataProvider.hookToRootScope() в true. Наконец, добавление данных,RouteData например

RouteData: {
      bodyStyle: {
        'background-color': 'green'
      }
    }

быть отправленным в $routeProvider и обработанным run() метод, определенный в модуле RouteData, который инициализирует параметры служб RouteData для доступа в приложении.

сценарий.js

angular.module('app', ['ngRoute', 'RouteData']).

config(['$routeProvider', 'RouteDataProvider', function($routeProvider, RouteDataProvider) {
  RouteDataProvider.applyConfig({
    bodyStyle: {
      'background-color': 'white'
    }
  });

  RouteDataProvider.hookToRootScope(true);

  $routeProvider.when('/landing', {
    RouteData: {
      bodyStyle: {
        'background-color': 'green'
      }
    },
    templateUrl: 'landing.html',
    controller: 'LandingController'  
  }).when('/login', {
    RouteData: {
     bodyStyle: {
         'background-color': 'gray',
         padding: '10px',
         border: '5px solid black',
         'border-radius': '1px solid black'
     }
    },
    templateUrl: 'login.html',
    controller: 'LoginController'
  }).otherwise({
    redirectTo: '/landing'
  });

}]).

controller('LoginController', ['$scope', function($scope) {

}]).

controller('LandingController', ['$scope', function($scope) {

}]);

таким образом, последний кусок кода, который будет добавлен на вашу страницу индекса или любой другая страница будет примерно такой.

часть index.html

<body ng-style="RouteData.get('bodyStyle')"> 
    <a href="#/landing">Landing</a> | 
    <a href="#/login">Login</a>
    <div ng-view></div>
</body>

один из способов стиля тела-добавить ng-view в качестве атрибута тела, затем используйте ng-class или ng-style (Я не использовал никакой другой вариант на сегодняшний день).

например:

<!doctype html>
<html ng-app="my-app">
  <head>
    <title>My Site</title>
    <script src="angular/angular.js"></script>
  </head>
  <body ng-class="{login:loginBody}" ng-view>
    <script src="my-app.js"></script>
  </body>
</html>

в этом примере login класс применяется к телу только тогда, когда loginBody является истинным значением в текущей области, установленным в контроллере входа.

это гораздо менее гибкий подход, чем подход, предлагаемый @ryeballar. В некоторых случаях этого может быть достаточно.


Я заметил, что при переходе на другую страницу без перезагрузки страницы цвет фона все еще остается, поэтому я делаю это (я использую angular ui-router):

в config:

$stateProvider.state('app.login',{
            url: '/login',
            onExit: function($rootScope){
                $rootScope.bodyClass = 'body-one';
            },
           templateUrl: 'ng/templates/auth/login-page-one.html',
            controller: function($rootScope){
                $rootScope.bodyClass = 'body-two';
            }
        })

        .state('app.signup',{
            url: '/signup',
            onExit: function($rootScope){
                $rootScope.bodyClass = 'body-one';
            },
            templateUrl: 'ng/templates/auth/signup-page-one.html',
            controller: function($rootScope){
                $rootScope.bodyClass = 'body-two';
            }
        });

в шаблоне

<body class="{{bodyClass ? bodyClass : 'body-one'}}">

в CSS:

.body-one{
    margin-top: 50px;
    background: #f0f4fb;
}

.body-two{
    margin: 0;
    padding: 0;
    background: #2e9fff;
}