27

I am aware of Angular Material which helps implement Material Design specification for use in Angular single-page applications.

I'm however taking a look at Material Design Lite alternative to integrate with my Angular project. I will like to know the best way to go about integrating Material Design Lite with and AngularJS app.

dantheta
  • 1,107
  • 2
  • 12
  • 29
  • http://www.getmdl.io/started/index.html – Sean Jul 07 '15 at 20:46
  • According to Material Design Lite, the advantage is that you don't need any JavaScript libraries for it to work, if you're already using AngularJS why not simply use Angular Material? – yvesmancera Jul 07 '15 at 20:55
  • @yvesmancera Even if he's using Angular, he might need a lite UI library. Check my answer for more details – Jad Joubran Jul 08 '15 at 20:10

5 Answers5

31

Emjay's second answer worked for me. You can additionally reduce boilerplate by tossing the upgradeAllRegistered method into Angular's run block:

angular.module('app', [])
    .run(function ($rootScope,$timeout) {
        $rootScope.$on('$viewContentLoaded', ()=> {
          $timeout(() => {
            componentHandler.upgradeAllRegistered();
          })
        })
      });
Yun-Chih Chen
  • 543
  • 5
  • 17
mpint
  • 498
  • 5
  • 11
  • Yep, I have changed my project to reflect this. Thanks. – kelsmj Jul 18 '15 at 13:32
  • I am quite new to angular and would really appreciate it if you could make a jsfiddle as an example to me. I'm running into the same problems with angular & MDL as OP – realappie Oct 07 '15 at 23:35
  • I find this to be working but there is a problem.. In latest version of MDL textfield autofocus is fixed and this isn't working when there is a $timeout call for componentHandler.upgradeAllRegistered(). It works without $timeout call, but there is still problem once you switch states in UI router. – dgrubelic Feb 10 '16 at 12:50
  • Additionally, upgrading all MDL components when ng-include loaded its content by registering on '$includeContentLoaded' event fixed random issues with navbar in my case. – Yann Sep 18 '17 at 18:51
12

Disclaimer: I am the author of this project

You can use Material Design Lite in your angular apps.
I believe you're looking for an angular wrapper on top of Material Design Lite.

There's this package under heavy development and it already has some directives implemented with configurable options (floating text fields) http://jadjoubran.github.io/angular-material-design-lite/

If you want a full UI written in angular, you can use Angular Material

Jad Joubran
  • 2,339
  • 3
  • 27
  • 57
  • If you're going to post links to your own projects, please put a disclaimer. – Xarus Jul 10 '15 at 13:08
  • @Xarus you're right! Thanks for the friendly notice. I fixed my answer – Jad Joubran Jul 10 '15 at 13:52
  • @JadJoubran If I use both angulat material and Material design lite, will there be any conflict ? – nicky Oct 16 '15 at 05:20
  • @nicky this is not recommended. But it might work well because each library has a different prefix/namespace for their css (mdl vs md). This explains the difference https://scotch.io/bar-talk/angular-material-vs-material-design-lite – Jad Joubran Oct 16 '15 at 05:49
12

I was having this problem rendering, more design elements dynamically using javascript CDM (eg menu) it was not rendered correctly. I created a solution to run componentHandler.upgradeDom () only when a new element is added:

var app = angular.module('app');
app.run(function () {
    var mdlUpgradeDom = false;
    setInterval(function() {
      if (mdlUpgradeDom) {
        componentHandler.upgradeDom();
        mdlUpgradeDom = false;
      }
    }, 200);

    var observer = new MutationObserver(function () {
      mdlUpgradeDom = true;
    });
    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
    /* support <= IE 10
    angular.element(document).bind('DOMNodeInserted', function(e) {
        mdlUpgradeDom = true;
    });
    */
});

Problem solved!

Dipen Shah
  • 1,835
  • 10
  • 26
  • 42
  • This works when using *Ionic* framework as well. Thanks! – Avijit Gupta Nov 21 '15 at 08:37
  • Nice, this just helped me for integrating MDL with Angular 2 :) – dSebastien Nov 26 '15 at 23:16
  • 2
    How efficient is this since it is observing the whole document.body right ? Is there any prformance trick here with MutationObserver that keeps this method performant ? – Lambros Petrou Dec 20 '15 at 19:59
  • Thanks. This provides an easy integration path for MDL menus with angularjs rendered components. I am using this run method just above controller on required pages only (you can have multiple angularjs run blocks) – rjha94 Jan 02 '17 at 13:03
8

You can include the .css and .js files like instructed on the Material Design Lite website, then just do the following when bootstrapping your app or when a controller loads.

angular.element(document).ready( 
      function() {
        componentHandler.upgradeAllRegistered();
    });

or

$scope.$on('$viewContentLoaded', () => {
  $timeout(() => {
    componentHandler.upgradeAllRegistered();
  })
});
kelsmj
  • 1,153
  • 11
  • 18
4

There is a less brute force way to upgrade the elements: no need for checking intervals or upgrading the whole DOM when something changes. MutationObserver already tells you exactly what's changed.

window.addEventListener('load', function() {
  var observer = new MutationObserver(function (mutations) {
    mutations.forEach(function( mutation ) {
      if (mutation.addedNodes)
        window.componentHandler.upgradeElements(mutation.addedNodes);
    })
  });
  observer.observe(document.body, {
      childList: true,
      subtree: true
  });
});
John Hardy
  • 528
  • 5
  • 6