AngularJS2如何使用TypeScript将依赖项注入到我的组件中

时间:2016-06-30 14:55:45

标签: dependency-injection typescript angular

我看到了各种版本的如何将依赖项注入到我的组件中,有些版本对我有用,有些则不然。所以我想知道,有什么优点和缺点,建议的最佳做法是什么,为什么某些不能按预期工作。这是一个例子:

@Component()
@Injectable()
class MyComponent {

  dependency1: Dependency1;

  constructor(dependency2: Dependency2, dependency3: Dependency3) {
    this.dependency2 = dependency2;
  }

  someFunction() {
    // Which of those will work, which is the best practice,
    //what are pros and cons
    this.dependency1.get();
    this.dependency2.get();
    this.dependency3.get();
  }
}

所以基于这个例子:

  1. 版本1(Dependency1)是否等同于版本2(Dependeny2)?或者版本1仅适用于TypeScript而与注射没有任何关联?

  2. 这行代码是

    this.dependency2 = dependency2;

  3. 必须做到这一点"自动化"喜欢假设为Dependency3?

    1. 什么是可注射的做法?如果没有它,问题1和2的答案会有何不同?
    2. 非常感谢

2 个答案:

答案 0 :(得分:3)

您似乎正在混合使用typescript 参数属性和Angular2 DI机制。

基本上,在使用typescript定义构造函数时,您有两个选项。简短版本:

@Component()
class MyComponent {
  constructor(
    public dependency1: Dependency1, 
    public dependency2: Dependency2, 
    public dependency3: Dependency3
  ) { }

  // [...]

这将转换为您也可以使用的更长,更详细的版本:

@Component()
class MyComponent {
  public dependency1: Dependency1;
  public dependency2: Dependency2;
  public dependency3: Dependency3;

  constructor(
    dependency1: Dependency1, 
    dependency2: Dependency2, 
    dependency3: Dependency3
  ) {
    this.dependency1 = dependency1;
    this.dependency2 = dependency2;
    this.dependency3 = dependency3;
  }

  // [...]

Typescript Handbook对此进行了解释。 两者都有他们的专业人士缺点,较长的版本对于打字稿的新手来说更容易理解和清晰,而后者则节省了相当多的打字,所以选择你的毒药。 :)

注意:如果您的类已经有另一个装饰器,则不需要@Injectable()装饰器,它只用于通过typescript强制生成元数据,它只适用于装饰类用不必要的元数据防止膨胀的代码。

关于DI技工,假设您导入了定义以及Dependency1,Dependency2和Dependency3(1),注册了他们的提供者(2)和angular创建了组件的实例(3):

  • 内部someFunction() this.dependency1是一个声明的(在您班级的开头是公开的)并且具有针对所有打字关注的已定义类型(Dependency1)。但是它的当前值是undefined,因为它没有在构造函数(或其他任何地方)中赋值。

    修复dependency1: Dependency1参数添加到构造函数并指定this.dependency1 = dependency1或使用上面的typescript短文([编辑] {{1 }})。

  • 在构造函数中访问constructor(public dependency1, ...会引发编译错误,因为this.dependency2没有属性MyComponent。在不太可能的情况下,这会编译/转换,然后dependency2应该具有正确的值,尽管您不会有this.dependency2的类型信息()。

    修复:为您的组件添加this.dependency2声明,例如。在构造函数[编辑]上方添加this.dependency2,或在构造函数public dependency2: Dependency2;参数public)前面添加dependency2属性。

  • 最后但并非最不重要constructor(public dependency2, ...有上述两个问题,没有声明(例如this.dependency3)和dependency2作为值(例如undefined)。< / p>

    修复:见上文。 ;)

注意:了解declaration & definition这是关于C ++,但也适用于打字稿以及)之间的区别很重要,我希望在拍打时我没有混淆条款。 ;)

  1. 例如通过:

    完成
    dependency1
  2. 有多种方法可以为依赖项定义提供程序

    • 在bootrap期间。这使得模块(通过其提供者)可用于应用程序中的每个组件。

      import { Dependency1 } from 'dependency-module-1';
      import { Dependency2 } from 'dependency-module-2';
      import { Dependency3 } from 'dependency-module-3';
      
    • 使用组件装饰器。这使得模块可用于MyComponent,相同的模块实例可用于每个子组件。 如果子组件hovever具有自己的提供者数组,则会为其生成 new 模块实例(并且与所有子组件的 shared 一样)。推荐的阅读材料是official Angular2 guidethis博文。这是一个例子:

      bootstrap(AppComponent, [
        Dependency1,
        Dependency2,
        Dependency3
      ]);
      
  3. MyComponent是为angulars bootstrap方法传递的(第一个)参数,或者在DOM中的某个地方使用组件选择器。

  4. 关于最佳做法,您可以尝试使用tslint和令人敬畏的custom-rule-plugins,例如。 codealyze one是特定于角度的。

    最后但并非最不重要的还有官方的Angular Typescript Styleguide。 ;)

答案 1 :(得分:0)

请查看官方documentation

另请查看此blog

Angular基于constructor based dependency injection。 简而言之,这意味着构造函数参数作为依赖注入 Car(e:Engine)

然后引擎将在汽车实例中通过DI注入。

现在你的所有代码都是Typescript定义构造函数的方法。以下2个代码是等效的。

e: Engine Car(e:Engine){ this.e = e }

Car(public e:Engine){ }