【问题标题】:Integrating Material Design Lite with Angular2将 Material Design Lite 与 Angular2 集成
【发布时间】:2016-03-29 01:49:55
【问题描述】:

我在 ng2 中集成一个计量设计 (http://www.getmdl.io/) 时遇到了一个小问题 你能帮我么 我会用我所做的来说明这一点

  1. http://www.getmdl.io/started/index.html#tab1,解释设计的集成
  2. http://www.getmdl.io/components/index.html#textfields-section,这是一个带有浮动标签的文本字段示例 现在我有Plunkr,我集成了它,但没有工作 你能看看吗 正如您在 index.html 中看到的,我包含 http://www.getmdl.io/started/index.html#tab1 建议的 css 和 js 文件

<!-- GetMDL scripts --> <link rel="stylesheet" href="https://storage.googleapis.com/code.getmdl.io/1.0.6/material.indigo-pink.min.css"> <script src="https://storage.googleapis.com/code.getmdl.io/1.0.6/material.min.js"></script> <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> <!-- GetMDL scripts --> 在 app.component.ts 文件中:

import {Component, ViewEncapsulation} from 'angular2/core';

@Component({
    selector: 'my-app',
    template: `<form action="#">
  <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
    <input class="mdl-textfield__input" type="text" id="sample3">
    <label class="mdl-textfield__label" for="sample3">Text...</label>
  </div>
</form>`,
encapsulation:ViewEncapsulation.None,
})

【问题讨论】:

  • 这里的答案非常有用,但我发现在处理路由器正在渲染的组件时它们还不够。如果您遇到与路由器相关的问题,您可能会对this question(和答案)感兴趣。

标签: typescript integration angular


【解决方案1】:

问题在于,Material Design Lite 并非设计用于动态页面,例如 Angular2 生成的页面。也就是说,使用 MDL componentHandler.upgradeElement 函数应该是可能的。

更多信息可以在这里找到: http://www.getmdl.io/started/#dynamic

我建议在您的 Angular 组件中获取一个 ElementRef,然后在您的组件生命周期挂钩之一中的元素 ref 上调用此函数,可能是 ngAfterViewInit()

【讨论】:

    【解决方案2】:

    只需从angular2/core 导入ElementRefOnInit 并将其注入到构造函数中:

    constructor(@Inject(ElementRef) elementRef: ElementRef) {
        this.elementRef = elementRef;
    

    }

    然后使用ngOnInit 方法并在您使用的任何动态添加的标签上使用componentHandler.upgradeElement

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题(因为我使用的模板与您相同)。

      试试componentHandler.upgradeAllRegistered(),它会在你的情况下正常工作。

      当您尝试将标头分解为小组件时会出现不同的问题。

      【讨论】:

        【解决方案4】:

        我可以从 angualrjs 频道获得解决方案,这是非常酷的解决方案,我们必须使用 componentHandler.upgradeElement(this.elementRef.nativeElement);

        //这是制作方法

        @Directive({
          selector: '[mdlUpgrade]'
        })
        class MdlUpgradeDirective {
          @Input() mglUpgrade;
        
          constructor(el: ElementRef) {
            componentHandler.upgradeElement(el.nativeElement);
          }
        }
        
        @Component ({
          selector: 'login',
           ...
          directives: [MdlUpgradeDirective]
        })
        

        并使用 HTML 标签上的指令来使用它。

        有效,

        注意:https://github.com/justindujardin/ng2-material,这家伙做了超酷的材料,也可以参考一下

        【讨论】:

        • 你真的同时使用 MDL + ng2-material 吗?您是否对 MDL 组件有任何问题(angular2 为每个阻碍其视图的组件创建父标签/选择器)?
        • 我发现在ngAfterViewInit() 中调用componentHandler.upgradeElement(el.nativeElement); 时效果更好(否则升级在其他指令之前完成,例如ngModel,开始执行)
        • 我不是质疑您提供的解决方案,只是澄清您提供的链接的一些内容。上面提到的文章是引用Material2,而不是Material Design Lite,这点不同。
        • @Helzgate,如果你读了整行,你会有一个想法,它基本上是其他设计的参考。
        • 我不得不说,我很困惑,为什么简单的在html元素上添加类的解决方案需要这么复杂?
        【解决方案5】:

        谢谢各位, 就像一个魅力,把它包装成一个完整的解决方案,对我来说效果很好(用 beta6 测试)。没有太多样板代码。我唯一没有开始工作的是真正通过*ngFor 动态添加的元素,具体取决于组件变量。请参阅模板中的dynamic elements。也许你们中的一个人知道如何解决这个问题。

        查看有效的plunkr(预览必须至少有 1024 像素宽才能看到标题)

        安装 MDL

        npm i material-design-lite --save
        

        在你的 index.html 中引用它

        <script src="/node_modules/material-design-lite/material.min.js"></script>
        <!-- from http://www.getmdl.io/customize/index.html -->
        <link rel="stylesheet" href="/css/customized-material.min.css">
        

        创建MaterialDesignLiteUpgradeElement.ts

        import {Directive, AfterViewInit} from 'angular2/core';
        declare var componentHandler: any;
        
        @Directive({
            selector: '[mdl]'
        })    
        export class MDL implements AfterViewInit {
            ngAfterViewInit() {
                componentHandler.upgradeAllRegistered();
            }
        }
        

        然后在你的组件中导入并注册它

        import { Component } from '@angular/core';    
        import { MDL } from '../../../directives/MaterialDesignLiteUpgradeElement';
        
        @Component ({
          selector: 'my-component',
          directives: [ MDL ],
          templateUrl: 'app/components/Header/Header.html'
        })
        export class Header {
          public dynamicArray:number[] = [];
        
          add() {
            this.dynamicArray.push(Math.round(Math.random() * 10));
          }
        }
        

        在你的模板中添加mdl到根组件

        <header mdl class="mdl-layout__header">
            <div class="mdl-layout__header-row">
              <span class="mdl-layout-title">Home</span>
              <div class="mdl-layout-spacer"></div>
        
              <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon"
                      (click)="add()">
                  <i class="material-icons">add</i>
              </button>
              <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon" id="hdrbtn">
                  <i class="material-icons">more_vert</i>
              </button>
              <ul class="mdl-menu mdl-js-menu mdl-js-ripple-effect mdl-menu--bottom-right" for="hdrbtn">
                  <li class="mdl-menu__item">Static entry</li>
        
                  <!-- semi dynamic, known when view is created -->
                  <li class="mdl-menu__item" *ngFor="#nr of [1,2,3]">Semi Dynamic entry {{nr}}</li>
        
                  <!-- dynamic, depends on service manipulated array -->
                  <li class="mdl-menu__item" *ngFor="#nr of dynamicArray">Dynamic entry {{nr}}</li>
              </ul>
          </div>
        </header>
        

        【讨论】:

        • 谢谢 Rob,这很有帮助。您注意到您无法添加动态元素。这不是您对菜单项所做的吗?也许您可以进一步解释。
        • 嗨史蒂夫,基本上任何在运行时生成的东西。半动态的东西可以在 OnInit 触发之前生成,因为 [1,2,3] 是已知的,因此可以渲染相应的视图。 dynamicArray 的内容不是。我们改用 ng2-material,效果更好。
        • 更好的解决方案是使用AfterViewChecked 接口,以便在根应用程序组件上只执行一次。在这里查看我的完整答案:stackoverflow.com/a/39040342/1969987
        • 我得到的指令在类型组件中不存在......还有其他人遇到这个吗?我是否需要同时使用 beta 版本('angular2/core')和发布版本('@angular/core')才能工作?
        • 对于初始视图加载后动态添加的元素,可以尝试使用ngAfterContentChecked()代替AfterViewChecked
        【解决方案6】:

        只是觉得这里值得一提的是,官方 Material Design for Angular 2 库现在处于 alpha.2 中,因此您可以考虑使用它开始新项目。

        【讨论】:

        • 我看了这个,我不完全明白如何在项目中使用它。如果有人有一个例子,我很想看看!
        • 或者如果你愿意,我可以在今天晚些时候从我的项目中复制一个 sn-p
        • 一年后,他们仍然没有实现表格等基本组件。这真的没有准备好生产,不要犯同样的错误。
        【解决方案7】:

        ng2-webpack Demo project 包含一个使用 vanilla MDL 的简单 ng2 CRUD 应用程序

        步骤:

        • npm install --save material-design-lite
        • 在 src/vendor.js 中导入整个库
        • 或只是所需的组件
        • 在 src/style/app.scss 中,导入所需的组件:

        问题:

        问题 - 未应用 MDL 增强的 DOM 效果:

        • 在状态变化期间始终如一
        • 路线变更期间

        解决办法:

        ngAfterViewInit() {
            // Ensure material-design-lite effects are applied
            componentHandler.upgradeDom();
        }
        

        查看Working with Material Design Lite了解更多详情。

        【讨论】:

          猜你喜欢
          • 2016-05-22
          • 2017-03-22
          • 2016-07-15
          • 1970-01-01
          • 2016-07-09
          • 2016-10-18
          • 2017-06-18
          • 2016-07-02
          • 1970-01-01
          相关资源
          最近更新 更多