Angular 2/4: 是否可以将 类 封装在 NgModule 中?

Angular 2/4: Is it possible to encapsulate classes in a NgModule?

我有几个 classes 我想包含在一个模块中,所以我可以导入模块,因为它是一个不同的包,并使用来自的那些 classes它。这是一个小例子:

human.ts(我的class文件)

export class Human {

  private numOfLegs: Number;

  constructor() {
    this.numOfLegs = 2;
  }
}

test.module.ts(我的模块文件)

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { Human } from './human';

@NgModule({
  imports: [CommonModule],
  declarations: [
    Human
  ],
  providers: [],
  exports: [Human]
})
export class TestModule {}

如何在组件中实例化人类 class? 我都试过了:

import { TestModule } from './test.module';

import { Human } from './test.module';

但如果我这样做 new Human() 我仍然得到 cannot find name Human

使人类 class 可注入并在测试模块的提供者部分声明它。

如果您的应用程序模块(根模块)急切地加载测试模块,则测试模块中声明的提供程序将在应用程序模块中可用,您将能够从根模块将 Human 注入到您的组件中.

如果您延迟加载测试模块,情况会有所不同 - 它们有自己的注入器,并且不与其他模块共享提供程序。

@NgModule({
  imports: [CommonModule],
  providers: [Human]
})
export class TestModule {}

我假设您正在使用路由器配置加载 TestModule:

@NgModule({
  imports: [ BrowserModule, TestModule,
    RouterModule.forRoot([
      {path: 'test', loadChildren: TestModule},
      )
  ],
    bootstrap:    [ AppComponent ]
})

在 AppComponent 中你可以注入 Human:

export class AppComponent {

  constructor(human: Human) {
    console.log(human.numOfLegs);
  }
}

确保 numOfLegs 为 public。

Angular 模块和 ES6 / TypeScript / Node 模块不同。 Angular 模块是组件、服务和指令的集合;而 ES6 模块在大多数情况下由 类 组成。

如果您想重用依赖于其他非 Angular 类 的 NgModule,您可以将它们导出为 ES6 模块并在其他地方使用它们。有一个类似 export.ts 或 index.ts 的文件,并将以下导出语句放在那里 -

export { TestModule } from './test.module';
export { Human } from './human';

现在,当你想在某个地方使用 NgModule 时,你可以使用如下命令导入它 -

import { TestModule } from '../lib/export'; 

A class 不应该在 declarationsexports 中提供,这些用于组件指令和管道,提供 Human 有错误。

第一个选项是 Human 在模块中作为值提供者(而不是 class 提供者)提供,因此应该手动实例化。当 class 接受非 DI 参数时,首选此选项。

@NgModule({
  providers: [{ provide: Human, useValue: Human }]
})
export class TestModule {}

...

import { Human } from '...';

@Component(...)
class SomeComponent {
  constructor(@Inject(Human) Human: typeof Human) {
    this.human = new Human();
  }
}

第二个选项是使 Human 成为组件提供者。它为每个组件实例实例化。在这种情况下 TestModule 是多余的。通常首选此选项:

import { Human } from '...';

@Component({ providers: [Human], ... })
class SomeComponent {
  constructor(public human: Human) {}
}

在这两种情况下Human DI 令牌应该导入到使用它的组件文件中。