Change body background color with angularjs

I want to change the background color of the <body> depending on the current path.

I tried to do this by checking $ location.path () whenever the path was changed, and then using the ng-style directive to change the background color, but this seems like a hack (and doesn't work).

What would be a more untied way to achieve this?

Here is the code I wrote if someone wants to see it.

 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'}; } }); }]); 
+6
source share
3 answers

To separate such dynamic changes in style, data, content, etc., it is often useful to create another angular module that contains an interface (user provider) that can give you access to these changes before and after the configuration level. Here is a plunker to provide an idea of ​​what I will discuss below.

For this answer, I created a small module (route-data.js) with provider , RouteData, which exposes two configurations of functions:

applyConfig() - assigns parameters that will be available in the RouteData service. hookToRootScope() - intercepts the RouteData service in $rootScope , which makes it accessible to all child areas that will be created, and the entire application.

The RouteData provider has a RouteData() service that provides access to methods that set and receive the RouteData parameters that will be provided in the $routeProvider configuration.

(If you are not familiar with providers and services, read about it here )

(If you are not familiar with the config() and run() methods, you can read more in here )

Route-data.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]); } }); }]); 

The following is a description of the script how to use the RouteData module above, by introducing RouteDataProvider at the configuration level and applying default configurations such as bodyStyle via RouteDataProvider.applyConfig() , you can also add additional parameters before the application is fully running. Connect it to $ rootScope by setting RouteDataProvider.hookToRootScope() to true. Finally, adding data, RouteData , for example.

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

which must be sent to $ routeProvider and processed by the run() method defined in the RouteData module, which initializes the parameters for the RouteData services that will be available in the application.

script.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) { }]); 

Thus, the last piece of code that will be added on your index page or on any other page will be something like this.

The index.html part

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

One way to style the body is to add ng-view as the body attribute, then use ng-class or ng-style (I have not used another option to date).

For instance:

 <!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> 

In this example, the login class is applied to the body only when loginBody is the true value in the current scope set in the login controller.

This is much less flexible than the approach offered by @ryeballar. In some cases, this may be sufficient.

+4
source

I noticed that when I go to another page without reloading the page, the background color still remains, so I do this (I use angular ui-router ):

In configuration:

 $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'; } }); 

In the template

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

In CSS:

 .body-one{ margin-top: 50px; background: #f0f4fb; } .body-two{ margin: 0; padding: 0; background: #2e9fff; } 
0
source

All Articles