【问题标题】:Angular 2/4: Is it possible to encapsulate classes in a NgModule? [duplicate]Angular 2/4:是否可以在 NgModule 中封装类? [复制]
【发布时间】:2017-09-09 01:23:50
【问题描述】:

我有几个类想要包含在一个模块中,因此我可以只导入该模块,因为它是一个不同的包,并从中使用这些类。这是一个小例子:

human.ts(我的类文件)

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 {}

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

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

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

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

【问题讨论】:

  • 我认为您仍然必须在组件中导入 Human 才能使用它,就像您要使用 Http 或任何其他对象一样。
  • 在我曾经为重复投票的线程中,已经说明了答案。顺便说一句,如果你将服务导入到 NgModule 中,你仍然需要将类导入到你将使用它的组件中。 javascript 导入和 NgModule 导入是两个完全不同的东西,可能会有点混乱。
  • 那么我尝试做的事情错了吗?
  • 类不能封装到模块中?

标签: angular typescript ng-modules


【解决方案1】:

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'; 

【讨论】:

  • 但这只是一个 ES6 模块,而不是 NgModule
  • 只要满足节点依赖关系,NgModule 应该可以在 Angular 环境中的任何地方工作。毕竟,模块就是类。
  • 顺便说一句,这就是我要找的。只是一种在模块中包装多个类的方法。谢谢
【解决方案2】:

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

第一个选项是Human在模块中作为值提供者(而不是类提供者)提供,所以应该手动实例化它。当类接受非 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 令牌都应导入到使用它的组件文件中。

【讨论】:

    【解决方案3】:

    使 Human 类可注入并在测试模块的提供程序部分中声明它。

    如果您的应用程序模块(根模块)急切地加载测试模块,则在测试模块中声明的提供程序将在应用程序模块中可用,您将能够从根模块将 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 是公开的。

    【讨论】:

    • 我把它变成了可注入的,并将它声明为我的模块的提供者。但是我如何访问它?导入后尝试了 TestModule.Human ,但它不起作用。你能举个小例子吗?
    • 在我的答案中添加了一些代码。
    猜你喜欢
    • 1970-01-01
    • 2019-10-03
    • 2014-07-10
    • 2012-09-04
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    相关资源
    最近更新 更多