使用Angular2与Material Design Lite

6
我正在学习Angular2,但是我在使用MDL时遇到了一些问题。为什么MDL导航栏在与Angular2一起使用时无法工作?当我将导航栏与标题和抽屉结合使用时,抽屉无法工作,因此我无法单击它,也无法看到抽屉图标。
还有另一个问题:文本字段也无法正确工作。我想使用mdl-textfield--expandable(搜索),但是当我单击此搜索字段时,它不会展开。然而,如果没有Angular2,则可以正常工作。 更新: 这是我的app.html文件:
<div class="demo-layout-waterfall mdl-layout mdl-js-layout">
    <header class="mdl-layout__header mdl-layout__header--waterfall">
        <!-- Top row, always visible -->
        <div class="mdl-layout__header-row">
            <!-- Title -->
            <span class="mdl-layout-title">Title</span>
            <div class="mdl-layout-spacer"></div>



            <div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable
                  mdl-textfield--floating-label mdl-textfield--align-right">
                <label class="mdl-button mdl-js-button mdl-button--icon" for="waterfall-exp">
                    <i class="material-icons">search</i>
                </label>
                <div class="mdl-textfield__expandable-holder">
                    <input class="mdl-textfield__input" type="text" name="sample" id="waterfall-exp">
                </div>
            </div>


        </div>
        <!-- Bottom row, not visible on scroll -->
        <div class="mdl-layout__header-row">
            <div class="mdl-layout-spacer"></div>
            <!-- Navigation -->
            <nav class="mdl-navigation">
                <a class="mdl-navigation__link" href="">Link</a>
                <a class="mdl-navigation__link" href="">Link</a>
                <a class="mdl-navigation__link" href="">Link</a>
                <a class="mdl-navigation__link" href="">Link</a>
            </nav>
        </div>
    </header>

    <div class="mdl-layout__drawer">
        <span class="mdl-layout-title">Title</span>
        <nav class="mdl-navigation">
            <a class="mdl-navigation__link" href="">Link</a>
            <a class="mdl-navigation__link" href="">Link</a>
            <a class="mdl-navigation__link" href="">Link</a>
            <a class="mdl-navigation__link" href="">Link</a>
        </nav>
    </div>

    <main class="mdl-layout__content">
        <div class="page-content">
            <!-- Your content goes here -->
            
           

        </div>
    </main>
</div>

app.ts

import { Component } from 'angular2/core';


@Component({
    selector: 'my-app',
    templateUrl: 'app/app.html',
    styleUrls: ['app/assets/css/material.min.css']

})
export class AppComponent { }

main.ts

import {bootstrap}    from 'angular2/platform/browser'
import {AppComponent} from './app.component'

bootstrap(AppComponent);

1
欢迎来到StackOverflow。请查看帮助菜单以了解如何提出好问题。请添加演示您尝试过的代码。解释实际和期望的行为是什么。"不起作用"并不包含任何有用的信息。 - Günter Zöchbauer
我已经解释了哪些部分不起作用。它只是没有显示抽屉的任何内容!代码是众所周知的,因为它在(MDL网站)上。 - Soulmaster
1
请再次阅读我上面的评论,并对每个句子做出回应。否则,您获得有用回复的机会将为0。 - Günter Zöchbauer
@GünterZöchbauerm,我已经添加了,你能回答吗? - Soulmaster
我认为下面的答案是一个很好的猜测。 - Günter Zöchbauer
angular-material和angular-material2标签与此问题无关,应予删除。 - Splaktar
2个回答

14

如@talkdirty所解释:

MDL组件处理器(您包含的MDL的js部分,用于处理动画和布局)并不知道您在模板中包含的MDL组件,因为它是由Angular2动态地包含在之后,MDL组件处理器寻找要处理的MDL组件。

他的解决方案可用于单个组件:

declare var componentHandler: any;
export class MyComponent {
    ngAfterViewInit(){
        componentHandler.upgradeAllRegistered();
    }
}

然而,在使用Angular2路由时,您需要在每个路由组件中添加此代码,这并不是非常智能和方便的。

作为解决方案,您可以使用 AfterViewChecked 接口代替 'AfterViewInit'

完整解决方案:
编写一个'mdl'指令,您将在应用程序组件的根HTML标记上使用它。

import {Directive, AfterViewChecked} from '@angular/core';
declare var componentHandler: any;

@Directive({
    selector: '[mdl]'
})
export class MDLUpgradeElementDirective implements AfterViewChecked {
    ngAfterViewChecked() {
        componentHandler.upgradeAllRegistered();
    }
}

接着按以下方式声明您的根组件:

import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';
import { MDLUpgradeElementDirective } from './mdl-upgrade-element.directive';

@Component({
  moduleId: module.id,
  selector: 'app-root',
  template: '
  <div mdl class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
    <header class="mdl-layout__header">
      <div class="mdl-layout__header-row">
        <!-- Title -->
        <span class="mdl-layout-title">{{title}}</span>
      </div>
    </header>
    <main class="mdl-layout__content">
      <!-- Router Outlet -->
      <router-outlet></router-outlet>
    </main>
  </div>
  '
  directives: [
    ROUTER_DIRECTIVES,
    MDLUpgradeElementDirective
  ]
})
export class AppComponent {
  title = 'MDL Application';
}

那么您就不需要再担心每个组件和路由上的 mdl js 处理程序了。


谢谢!甚至可以在@angular@2.0.0-rc.5上工作。 - Leo Caseiro
适用于Angular 2 RTM与1.3.0版的Material JS。请确保您在脚本标记或组件处理程序中不使用“defer”,否则会导致未定义。 - Sean Chase
@Julien Boulay,你的解决方案已经不再适用了,我得到了与帖子相同的错误。更新一下解决方案会很有帮助。 - Deep 3015

4

由于您没有发布任何代码示例,我猜测您处于以下情况中(这是在使用MDL和Angular2时的常见陷阱):您在Angular 2 @Component模板中包含了MDL。

@Component({
    template: `mdl things here`,
    ....
}) export class YourComponent {}

如果是这种情况,MDL组件处理程序(即包含在您中的js部分,用于处理动画和布局的MDL)不知道模板中包含的mdl组件,因为它是由Angular2动态包含的。在MDL组件处理程序查找要处理的MDL组件后的某个时间点。
简而言之,在组件初始化后告诉MDL重新检查DOM以处理新组件。
declare var componentHandler: any;
export class MyComponent {
    ngAfterViewInit(){
        componentHandler.upgradeAllRegistered();
    }
}

我已经添加了componentHandler。然而,它并没有解决我的问题。 - Soulmaster
1
ngAfterViewInit() 只会触发一次,这意味着之后发生的模板更改不会被捕获。如果使用 ngAfterContentChecked(),它将在应用程序加载时工作,并升级事后添加的任何组件。 - estaples
我知道这是老问题,但是Angular如何知道在这个上下文中componentHandler是什么? - Feign

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