I\'m building an Angular application using Angular Material. One of the first steps in the application is that the user logs in. Next, the system loads from the backend the
<your_module>.config(function ($mdThemingProvider, $provide) {
$provide.value('$mdThemingProvider', $mdThemingProvider);
});
Now you can inject $mdTheming
and $mdThemingProvider
in your controller and insert the code below in your controller.
$mdThemingProvider.theme(<theme_name>).primaryPalette(<primary_color>).accentPalette(>accent_color>);
$mdTheming.generateTheme(<theme_name>);
If you want this to be your default theme, then:
$mdThemingProvider.setDefaultTheme(<theme_name>);
or use md-theme="<theme_name>"
in HTML.
PS: Works with Angular Material 1.1 and above.
I have managed to fix this by making some minor changes to the provider. To allow themes to be changed:
First, modify the generateThemes function in angular-material.js to set generationIsDone = false.
This will allow you to regenerate the themes at a later time.
function generateThemes($injector) {
var styles = $injector.has('$MD_THEME_STYLESHEETS') ? $injector.get('$MD_THEME_STYLESHEETS') : [];
if (styles) {
var $q = $injector.get('$q');
var $http = $injector.get('$http');
var calls = [];
angular.forEach(styles, function(style){
calls.push($http.get(style));
});
$q.all(calls).then(function(responses) {
var css = '';
angular.forEach(responses, function(response) {
css += response.data;
});
generationIsDone = false; // here
generateCss(css);
});
} else {
var css = $injector.has('$MD_THEME_CSS') ? $injector.get('$MD_THEME_CSS') : '';
generationIsDone = false; // here
generateCss(css);
}
}
Second, make the generateThemes() function available as a property on the ThemingService.
You can call it when you have added new themes, to generate their CSS.
ThemingService.$inject = ["$rootScope"];
return themingProvider = {
definePalette: definePalette,
extendPalette: extendPalette,
theme: registerTheme,
setDefaultTheme: function(theme) {
defaultTheme = theme;
},
alwaysWatchTheme: function(alwaysWatch) {
alwaysWatchTheme = alwaysWatch;
},
reload: generateThemes, // here
$get: ThemingService,
_LIGHT_DEFAULT_HUES: LIGHT_DEFAULT_HUES,
_DARK_DEFAULT_HUES: DARK_DEFAULT_HUES,
_PALETTES: PALETTES,
_THEMES: THEMES,
_parseRules: parseRules,
_rgba: rgba
};
Third, to actually make the ThemingProvider available to your controllers, add it to your module as a value.
angular.module("yourModule",['whateverDependencies']) .config(function($provide, $mdThemingProvider) { $provide.value('themeProvider', $mdThemingProvider); // now you can inject the provider })
And finally, where you need it, just call for the value in your controllers:
}).controller('someController', function(themeProvider, $injector) {
themeProvider.theme('someNewTheme').primaryColor('orange').accentColor('pink');
themeProvider.reload($injector);
}
I was also having a similar scenario, CSS has provided us a feature called var(), which allows us to runtime change properties of our CSS elements. Check my blog for more details here, hope this will help you
This is easier now. You only have to omit the first step. In resume:
reload: generateThemes
in themingProvider
function (angular-material.js)Make the provider available to your controllers:
$provide.value('themeProvider', $mdThemingProvider);
Create your theme in your controller using themeProvider
themeProvider.reload($injector);
The following worked for me, all credit to Guilhermecvm, however I'll add the code from the Github issue in case google brings anyone else here
angular.module('app')
.config(['$mdThemingProvider', '$provide', function($mdThemingProvider, $provide) {
$mdThemingProvider.generateThemesOnDemand(true);
$provide.value('themeProvider', $mdThemingProvider);
}])
.controller('AppController', ['themeProvider', '$mdTheming', function(themeProvider, $mdTheming) {
//create new theme
themeProvider.theme('default')
.primaryPalette('pink')
.accentPalette('orange')
.backgroundPalette('yellow');
//reload the theme
$mdTheming.generateTheme('default');
//optional - set the default to this new theme
themeProvider.setDefaultTheme('default');
}]);
To avoid 'attempted to use unregistered theme' warnings, the theme should be added to the mdTheming internal list of themes
var theme = themeProvider.theme...
$mdTheming.THEMES[themeName] = theme;
As of version 1.0.5 of angular-material:
Add
reload: generateTheme
in themingProvider function (angular-material.js line 4840 - the generateTheme function is already present in angular-material.js, we just need a way to call it)
In config function:
angular.module('my-module').config(function ($provide, $mdThemingProvider) {
$mdThemingProvider.generateThemesOnDemand(true);
$provide.value('themeProvider', $mdThemingProvider);});
In your controller, inject themeProvider and now you can do something like:
//create new theme
themeProvider.theme('custom')
.primaryPalette('pink')
.accentPalette('orange')
.backgroundPalette('yellow');
//reload the theme
themeProvider.reload('custom');
//optional - set the default to this new theme
themeProvider.setDefaultTheme('custom');