如何在 Angular2 App 中使用 OverlayModule (angular2-material)
How to use OverlayModule (angular2-material) in Angular2 App
注意:我不使用 Angular-Cli
OverlayModule 似乎是其他 angular2-material 组件所必需的。
zone.js:355 Unhandled Promise rejection: Error in ./AppComponent class
AppComponent - inline template:2:2 caused by: No provider for Overlay!
; Zone: ; Task: Promise.then ; Value:
我已经安装了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',
},
我正在为 angular2-material 组件使用 sharedModule 以便它们随处可用。
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>
有几个选项:
- 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 ]
};
}
- 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()
总是 return 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
只是添加到 。
首先要提到的是 forRoot()
不应导入到共享模块中,原因已提到 。现在应该从中提取提供者以添加共享模块 @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() ]
风格方面,我想我可能会走这条路。
注意:我不使用 Angular-Cli
OverlayModule 似乎是其他 angular2-material 组件所必需的。
zone.js:355 Unhandled Promise rejection: Error in ./AppComponent class AppComponent - inline template:2:2 caused by: No provider for Overlay! ; Zone: ; Task: Promise.then ; Value:
我已经安装了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',
},
我正在为 angular2-material 组件使用 sharedModule 以便它们随处可用。
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>
有几个选项:
- 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 ]
};
}
- 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()
总是 return 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
只是添加到
首先要提到的是 forRoot()
不应导入到共享模块中,原因已提到 @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() ]
风格方面,我想我可能会走这条路。