以角度动态加载材质主题

时间:2015-02-19 09:26:00

标签: angularjs material-design angular-material

我正在使用Angular Material构建一个Angular应用程序。该应用程序的第一步是用户登录。接下来,系统从后端加载该用户公司制作的主题。

但是,当后端响应主题信息时,我无法进入系统。允许您设置主题的$ mdThemingProvider似乎不能从Controller内部获得,并且$ mdTheming服务本身没有用于修改系统中主题的选项。

有没有办法将新主题动态加载到Angular Material应用程序中?

6 个答案:

答案 0 :(得分:4)

从角度材料版本1.0.5开始:

  1. 添加

    reload: generateTheme 
    

    在themingProvider函数中(angular-material.js第4840行 - generateTheme函数已存在于angular-material.js中,我们只需要一种方法来调用它)

  2. 在配置功能中:

    angular.module('my-module').config(function ($provide, $mdThemingProvider) {
     $mdThemingProvider.generateThemesOnDemand(true);
     $provide.value('themeProvider', $mdThemingProvider);});
    
  3. 在您的控制器中,注入themeProvider,现在您可以执行以下操作:

    //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');
    

答案 1 :(得分:3)

我设法通过对提供程序进行一些小的更改来解决这个问题。允许更改主题:

首先,修改angular-material.js中的generateThemes函数,设置generationIsDone = false。

这将允许您稍后重新生成主题。

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

其次,使generateThemes()函数可用作ThemingService的属性。

您可以在添加新主题时调用它,以生成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
  };

第三,要实际让控制器可以使用ThemingProvider,请将其作为值添加到模块中。

angular.module(" yourModule" [' whateverDependencies'])         .config(function($ provide,$ mdThemingProvider){             $ provide.value(' themeProvider',$ mdThemingProvider); //现在你可以注入提供者了         })

最后,在您需要的地方,只需调用控制器中的值:

}).controller('someController', function(themeProvider, $injector) {         

 themeProvider.theme('someNewTheme').primaryColor('orange').accentColor('pink');
  themeProvider.reload($injector);
}

答案 2 :(得分:2)

This is easier now. You only have to omit the first step. In resume:

  1. Add <!DOCTYPE html> <html> <head> <title>SVG</title> <meta charset="utf-8" /> <style> .dot { position: absolute; } #green{ left: 20px; top: 20px; } #orange{ left: 20px; top: 60px; } #red { left: 20px; top: 100px; background: red; height: 20px; width: 20px; } </style> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> </head> <body> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" baseProfile="tiny" id="green" class="dot" width="20" height="20"> <circle cx="10" cy="10" r="10" fill="green" /> </svg> <div id="orange" class="dot"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" baseProfile="tiny" width="20" height="20"> <circle cx="10" cy="10" r="10" fill="orange" /> </svg> </div> <div id="red" class="dot"></div> <script> $(function ready() { var dots = $(".dot") dots.on("mousedown touchstart", startDrag) var $doc var $dot var offsetX var offsetY function startDrag(event) { $doc = $(document) $doc.on("mousemove", drag) $doc.on("mouseup", stopDrag) $dot = $(event.target) var offset = $dot.offset() offsetX = offset.left - event.pageX offsetY = offset.top - event.pageY } function stopDrag(event) { $doc.off("mousemove mouseup") } function drag(event) { var left = event.pageX + offsetX var top = event.pageY + offsetY $dot.css({ left: left, top: top }) } }) </script> </body> </html> in reload: generateThemes function (angular-material.js)
  2. Make the provider available to your controllers:

    $provide.value('themeProvider', $mdThemingProvider);

  3. Create your theme in your controller using themeProvider

  4. Reload themes using themingProvider

答案 3 :(得分:0)

以下内容对我有用,全部归功于Guilhermecvm,但我会在Github issue添加代码,以防google将其他人带到此处

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

避免尝试使用未注册的主题&#39;警告,主题应添加到mdTheming内部主题列表

var theme = themeProvider.theme...
$mdTheming.THEMES[themeName] = theme;

答案 4 :(得分:0)

<your_module>.config(function ($mdThemingProvider, $provide) {
     $provide.value('$mdThemingProvider', $mdThemingProvider);
});

现在您可以在控制器中注入$mdTheming$mdThemingProvider,并在控制器中插入以下代码。

$mdThemingProvider.theme(<theme_name>).primaryPalette(<primary_color>).accentPalette(>accent_color>);
$mdTheming.generateTheme(<theme_name>);

如果您希望这是默认主题,那么:

$mdThemingProvider.setDefaultTheme(<theme_name>);

或在HTML中使用md-theme="<theme_name>"

PS:适用于Angular Material 1.1及以上版本。

答案 5 :(得分:0)

我也有类似的情况,CSS提供了一个名为var()的功能,该功能使我们能够在运行时更改CSS元素的属性。 检查我的博客以获取更多详细信息here,希望这会对您有所帮助