简体   繁体   English

为什么在此angular2示例中仍需要@inject?

[英]Why do I still need @inject in this angular2 example?

This is proably a special case (injecting the browsers native window object), but nevertheless I'm a bit confused about why I still need the @Inject() parameter-decorator when my class already has a @Injectable() decorator. 这可能是一种特殊情况(注入浏览器的本机窗口对象),但是尽管如此,当我的类已经具有@Injectable()装饰器时,为什么仍然需要@Inject()参数装饰器让我有些困惑。

Take this simplified example: 举这个简化的例子:

import { provide, bootstrap, Injectable, Inject } from '@angular/core';


@Injectable()
export class Token {
  private token: string;

  public constructor(token: string, window: Window) {
    this.token = window.atob(token);
  };

  public getToken(): string {
    return this.token;
  }
}


@Injectable()
export class TokenFactory {
  private window: Window;

  public constructor(window: Window) {
    this.window = window;
  }

  public createToken(token: string): Token {
    return new Token(token, this.window);
  }
}


@Component({
  template:   `
    <p *ngFor="let token of tokens">
      Encoded: {{token.getToken()}}
    </p>
  `,
  providers:  [ TokenFactory ]
})
class MainComponent {
  public tokens: Token[];

  public constructor(factory: TokenFactory) {
    this.tokens = [
      factory.create('token-1'),
      factory.create('token-2')
    ];
  };
}


bootstrap(
  MainComponent, [
    provide(Window, { useValue: window })
]);

Overview: We have a token class that represents an object that could exist multiple times inside a component or another service (so no singleton). 概述:我们有一个令牌类,它表示一个对象,该对象可以在组件或其他服务中多次存在(因此没有单例)。 The token class depends on the global window object (eg. for base64 encoding). 令牌类取决于全局窗口对象(例如,用于base64编码)。 To make this testable we define an app-wide provider for the global window object during bootstrap instead of using it directly in the token service. 为了使其可测试,我们在引导过程中为全局窗口对象定义了应用程序范围的提供程序,而不是直接在令牌服务中使用它。

The main component needs to create tokens dynamically, so we create and inject a simple factory-service TokenFactory which also needs the window provider (to pass it the the token class during construction). 主要组件需要动态创建令牌,因此我们创建并注入一个简单的工厂服务TokenFactory ,它也需要窗口提供程序(在构造过程中将令牌类传递给它)。

The Problem: This fails when executed in a browser with the error 问题:在浏览器中执行此错误时,此操作失败

Can't resolve all parameters for TokenFactory: (?).

but can be fixed by adding a @Inject(Window) decorator to the factories constructor window parameter. 但可以通过在工厂构造函数的window参数中添加@Inject(Window)装饰器来解决。

Now, I'm a bit confused, since most guides/tutorials explain that the inject decorator is not required in typescript when decorating the class with the Injectable decorator, so why does the example fail without using @Inject() decorator ? 现在,我有点困惑,因为大多数指南/教程都说明了在使用Injectable装饰器装饰类时,打字稿中不需要inject装饰器, 那么为什么在不使用@Inject()装饰器的情况下该示例失败

Config: emitDecoratorMetadata and experimentalDecorators settings are enabled and I'm using tsc 1.8.10 and angular2 rc.3 . Config:启用了embedDecoratorMetadataexperimentalDecorators设置,我使用的是tsc 1.8.10angular2 rc.3


PS: I'm also open for general design improvements. PS: 我也愿意进行一般性的设计改进。

(Eg. In a production scenario I would probably only export the Token interface and not the whole class) (例如,在生产场景中,我可能只会导出Token接口,而不是整个类)

It's unclear to me what the question actually is about but 我不清楚问题的实质是什么,但是

type string for a constructor parameter of an injectable doesn't make any sense without @Inject(...) 如果没有@Inject(...) ,则用于可注入的构造函数参数的类型string没有任何意义@Inject(...)

@Injectable()
export class Token {
  private token: string;

  public constructor(token: string, window: Window) { // <<== invalid
    this.token = window.atob(token);
  };

  public getToken(): string {
    return this.token;
  }
}

but because you are using it like 但是因为你像那样使用它

new Token(token, this.window);

it seems that just @Injectable() should be removed from this class. 似乎只是@Injectable()应该从此类中删除。


About the error message: It looks like Window is not properly imported or it is not a type but an OpaqueToken or a string . 关于错误消息:看起来Window没有正确导入,或者它不是类型,而是OpaqueTokenstring

@Inject() is required if a key that differs from the parameter type should be used by dependency injection. 如果依赖项注入应使用与参数类型不同的键,则需要@Inject() In your case it looks like Window is not a type (class) and therefore doesn't work when used as such. 在您的情况下, Window似乎不是类型(类),因此按原样使用时不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM