【问题标题】:How to use OverlayModule (angular2-material) in Angular2 App如何在 Angular2 App 中使用 OverlayModule (angular2-material)
【发布时间】:2017-02-02 06:51:31
【问题描述】:

注意:我不使用 Angular-Cli

OverlayModule 似乎是其他 angular2-material 组件所必需的。

zone.js:355 未处理的承诺拒绝:./AppComponent 类中的错误 AppComponent - 内联模板:2:2 原因:没有覆盖提供者! ;区域:;任务:Promise.then;价值:

我已经从 angular2-material 安装了所有包。

sytemjs.config.js

 map: {
      // our app is within the app folder
      app: 'dist',
      ...
      ...
      '@angular2-material/core': 'npm:@angular2-material/core/core.umd.js',
      '@angular2-material/button': 'npm:@angular2-material/button/button.umd.js',
      '@angular2-material/menu': 'npm:@angular2-material/menu/menu.umd.js',
      '@angular2-material/icon': 'npm:@angular2-material/icon/icon.umd.js',
      _____________________________________________________________________
      /*>>>>>   DO I NEED TO MAP ANYTHING FOR OVERLAY HERE?  <<<<<< */
      ______________________________________________________________________
      // other libraries
      'rxjs':                       'npm:rxjs',
      'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
    },

我将 sharedModule 用于 angular2-material 组件,以便它们在任何地方都可用。

shared.module.ts

import {MdButtonModule } from '@angular2-material/button';
import {MdIconModule} from '@angular2-material/icon';
import {MdMenuModule} from '@angular2-material/menu';
import {MdIconRegistry} from '@angular2-material/icon';

@NgModule({
  imports:      [ CommonModule ],
  declarations: [],
  exports:      [ CommonModule,MdButtonModule,MdMenuModule,MdIconModule],
})
export class SharedModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: SharedModule,
      providers: [ MdIconRegistry ]  //>>>>> DO I NEED TO ADD ANYTHING HERE ??
    };
  }
}

App.Module.ts

@NgModule({
  imports:      [ BrowserModule,SharedModule.forRoot()],  
  ...
})

HTML:

<button md-icon-button [md-menu-trigger-for]="menu">
   <md-icon>more_vert</md-icon>
</button>

<md-menu #menu="mdMenu">
    <button md-menu-item> Refresh </button>
    <button md-menu-item> Settings </button>
    <button md-menu-item> Help </button>
    <button md-menu-item disabled> Sign Out </button>
</md-menu>
<button md-raised-button>Button</button>

【问题讨论】:

  • 你能发布你的html吗?
  • 用 HTML 更新了我的问题。
  • github.com/jelbourn/material2-app/blob/master/src/app/… 在这里他们导入 OverlayModule 就像:import {OverlayModule} from '@angular2-material/core/overlay/overlay-directives'; 如果我尝试在 sharedModule 中做同样的事情,它会抛出错误,例如:http://localhost:3000/node_modules/@angular2-material/core/core.umd.js/overlay/overlay-directives 404 (Not Found)。我觉得我需要 systemjs.config.js 中的 map something 但最近发现 OverlayModule 没有 umd.js 所以无法在系统文件中映射任何内容。

标签: angular angular2-material


【解决方案1】:

有几种选择:

  • 1) 尝试在共享模块中导入OverlayModule,如下所示:

shared.module.ts

import {OverlayModule } from '@angular2-material/core';
@NgModule({
  imports:      [ CommonModule, OverlayModule.forRoot() ], <== here
  declarations: [],
  exports:      [ CommonModule,MdButtonModule,MdMenuModule,MdIconModule],
})
export class SharedModule {
  • 2) 可以在主模块中导入

  • 3) 或使用以下内容:

shared.module.ts

static forRoot(): ModuleWithProviders {
  return {
    ngModule: SharedModule,
      [ MdIconRegistry,  MdMenuModule.forRoot().providers ]
  };
}

Plunker Example

  • 4) 或者这样:

shared.module.ts

@NgModule({
  imports:      [ CommonModule, MdMenuModule.forRoot() ],
  declarations: [],
  exports:      [ CommonModule,MdButtonModule,MdMenuModule,MdIconModule],
})
  • 5) 只需将提供程序添加到您的 SharedModule

shared.module.ts

 import {OVERLAY_PROVIDERS } from '@angular2-material/core';
 return {
   ngModule: SharedModule,
   providers: [ MdIconRegistry,  OVERLAY_PROVIDERS ]
 };

forRoot() 总是返回 ModuleWithProviders 对象:

export interface ModuleWithProviders {
  ngModule: Type<any>;
  providers?: Provider[];
}

export class MdMenuModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: MdMenuModule,
      providers: OVERLAY_PROVIDERS,
    };
  }
}

https://github.com/angular/material2/blob/2.0.0-alpha.8/src/lib/menu/menu.ts#L21

【讨论】:

  • 太棒了。但是为什么import {OverlayModule } from '@angular2-material/core';我不明白。
  • 我试图给你+2,但我不能:(。我需要解释一下。
  • 你怎么知道MdMenuModule.forRoot().providers?有什么文件什么的?
  • 由于mentioned here 的原因,您不应该添加到提供程序或在共享模块导入中调用 forRoot
  • @micronyks 我猜MdMenuModule.forRoot().providers 就像你只是在提供者中导入OVERLAY_PROVIDERS 一样
【解决方案2】:

只需添加到accepted answer

首先要提到的是forRoot()不应该被导入共享模块,原因提到here。现在应该从中提取提供者以添加共享模块@NgModule.providers

@NgModule({
  imports: [ SomeModule.forRoot() ],
  providers: [ SomeModule.forRoot().providers ]
})
export class SharedModule {}

不要这样做。不在共享模块中。下面是可以的,虽然我不认为它应该这样使用

@NgModule({})
export class SharedModule {
  static forRoot() {
    return {
      ngModule: SharedModule,
      providers: [ SomeModule.forRoot().providers ]
    }
  }
}

就像我说的没关系,它会起作用,但它只是看起来很奇怪。也许更优雅的解决方案是 Material 自己提供的解决方案。如果您查看快照(截至目前 - 将在下一个版本中发布),您将看到他们在哪里制作了 module that consolidated all the MD modules。也许只是做他们正在做的事情,但不要添加所有模块,只需添加您使用的模块

const MATERIAL_MODULES = [
  MdButtonModule,
  MdIconModule,
  MdMenuModule
];

@NgModule({
  imports: [
    MdButtonModule.forRoot(),
    MdIconModule.forRoot(),
    MdMenuModule.forRoot()
  ],
  exports: MATERIAL_MODULES
})
export class MaterialRootModule {}

@NgModule({
  imports: MATERIAL_MODULES,
  exports: MATERIAL_MODULES
})
export class MaterialModule {
  static forRoot() {
    ngModule: MaterialRootModule
  }
}

在你的共享模块中只是

exports: [ MaterialModule ]

在应用模块中

imports: [ MaterialModule.forRoot() ]

风格方面,我想我可能会走这条路。

【讨论】:

  • 感谢您指出这一点。我提出在 forRoot 方法中添加SomeModule.forRoot().providers。我同意第一个说法。
猜你喜欢
  • 1970-01-01
  • 2016-12-12
  • 2016-12-11
  • 1970-01-01
  • 2016-10-09
  • 2016-10-18
  • 1970-01-01
  • 2017-03-22
  • 1970-01-01
相关资源
最近更新 更多