Material Design Lite与AngularJS的集成

27

我知道Angular Material,它有助于实现Material Design规范,并用于Angular单页应用程序。

然而,我正在查看Material Design Lite这个备选方案,以集成到我的Angular项目中。我想知道将Material Design Lite与AngularJS应用程序集成的最佳方法。


http://www.getmdl.io/started/index.html - Sean
根据Material Design Lite,它的优点是您不需要任何JavaScript库即可使其工作,如果您已经在使用AngularJS,为什么不直接使用Angular Material呢? - yvesmancera
@yvesmancera 即使他在使用Angular,他可能仍需要一个轻量级的UI库。请查看我的回答获取更多细节。 - Jad Joubran
5个回答

31

Emjay的第二个答案对我有用。你还可以将upgradeAllRegistered方法添加到Angular的run块中,以进一步减少样板代码。

angular.module('app', [])
    .run(function ($rootScope,$timeout) {
        $rootScope.$on('$viewContentLoaded', ()=> {
          $timeout(() => {
            componentHandler.upgradeAllRegistered();
          })
        })
      });

是的,我已经修改了我的项目以反映这一点。谢谢。 - kelsmj
我对Angular还很陌生,如果您能为我制作一个jsfiddle示例,我将不胜感激。我在使用Angular和MDL时遇到了与OP相同的问题。 - realappie
我发现这个程序可以工作,但是有一个问题。在最新版本的 MDL 中,textfield autofocus 已经被修复了,但是当 componentHandler.upgradeAllRegistered() 被 $timeout 调用时,它就无法工作了。如果没有 $timeout 的调用,它可以正常工作,但是一旦在 UI router 中切换状态,仍然会出现问题。 - dgrubelic
此外,通过在“$includeContentLoaded”事件上注册来加载其内容时升级所有MDL组件,可以解决导航栏出现的随机问题。 - Yann

12

免责声明:我是这个项目的作者

您可以在您的angular应用程序中使用Material Design Lite。我相信您正在寻找一个在Material Design Lite之上的angular封装。

现在有这个包正在积极开发中,它已经实现了一些具有可配置选项的指令(如浮动文本字段)http://jadjoubran.github.io/angular-material-design-lite/

如果您想要一个完整的UI,并且使用angular编写,那么您可以使用Angular Material


如果您打算发布自己项目的链接,请加上免责声明。 - Xarus
@Xarus 你说得对!感谢友好的提醒。我已经修正了我的回答。 - Jad Joubran
如果我同时使用Angular Material和Material Design Lite,会有任何冲突吗? - nicky
@nicky 这并不是推荐的做法。但是它可能会很好地工作,因为每个库都有不同的前缀/命名空间用于他们的 CSS(mdl vs md)。这解释了两者之间的区别 https://scotch.io/bar-talk/angular-material-vs-material-design-lite - Jad Joubran

12

我遇到了一个问题,使用JavaScript CDM(例如菜单)动态地呈现更多的设计元素时,它没有正确地呈现。我创建了一个解决方案,只在添加新元素时运行componentHandler.upgradeDom():

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

问题已解决!


这也适用于使用Ionic框架。谢谢! - Avijit Gupta
不错,这对我在将MDL与Angular 2集成方面有所帮助 :) - dSebastien
2
这种方法观察整个document.body,效率如何?使用MutationObserver有什么性能技巧可以保持方法的高效性吗? - Lambros Petrou
谢谢。这为MDL菜单与angularjs渲染组件提供了简单的集成路径。我仅在必要的页面上使用此运行方法(您可以拥有多个angularjs运行块),并将其放置在控制器上方。 - rjha94

8
您可以像在 Material Design Lite 网站上指示的那样包含 .css 和 .js 文件,然后在引导应用程序或控制器加载时执行以下操作。
angular.element(document).ready( 
      function() {
        componentHandler.upgradeAllRegistered();
    });

或者

$scope.$on('$viewContentLoaded', () => {
  $timeout(() => {
    componentHandler.upgradeAllRegistered();
  })
});

我使用了第一个解决方案,它解决了我的问题。谢谢! - MannIncognito

4

有一种更加高效的方式来升级元素:无需检查间隔或在某些更改时升级整个DOM。MutationObserver 已经能够准确告知哪些内容发生了变化。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接