38

我遇到了“不透明令牌”作为在 Angular 2 中实现全局常量的解决方案,例如这里:Define global constants in Angular 2

尽管阅读了文档,但我似乎无法理解这一点。

使用 OpaqueToken 比使用字符串作为令牌更可取,因为多个提供者使用相同的字符串作为两个不同的令牌可能会导致冲突。

什么?什么是 Angular2 令牌开始?我在谷歌上得到的只是关于 JSON Web Tokens 的答案(它们在身份验证中的作用等),我理解,但显然没有任何关系。

什么是不透明令牌?它是干什么用的?

PS 更多关于用于提供常量的不透明标记的文档。然而,他们并没有给我太多帮助。

4

4 回答 4

66

更新 Angular4

在 Angular4OpaqueToken中已弃用,将由InjectionToken. InjectionToken 允许传递泛型类型参数。

export let APP_CONFIG = new InjectionToken<MyConfig>("app.config");

也可以看看

原来的

什么?什么是 Angular2 令牌开始?

什么是不透明令牌?它是干什么用的?

令牌是 Angulars 依赖注入提供者的密钥。提供者使用密钥注册,并且由 DI 实例化的组件、指令和服务类获得注入的依赖项,这些依赖项由提供者密钥查找。

DI 支持类型、字符串OpaqueToken和对象作为键。

export let APP_CONFIG = new OpaqueToken("app.config");

export let APP_CONFIG_2 = {};

providers: [
  MyService, // type is key and value
  {provide: MyService, useClass: MyFancyServiceImpl}, // type is key, `MyFancyServiceImpl` is the value (or rather the information how to create the value
  {provide: 'myservice', useClass: MyService}, // key is a string
  {provide: APP_CONFIG, useValue: {a: 'a', b: 'b'}} // key is an `OpaqueToken`
  {provide: APP_CONFIG_2, useValue: {a: 'a', b: 'b'}} // key is an object

]
// one of these decorators needs to be added to make DI work
@Injectable()
@Component()
@Directive()
@Pipe()
class MyComponent {
  // DI looks up a provider registered with the key `MyService` 
  constructor(private myService: MyService) {} 

  // Same as before but explicit
  constructor(@Inject(MyService) private myService: MyService) {} 

  // DI looks up a provider registered with the key 'myService'
  constructor(@Inject('myservice') private myService: MyService) {} 

  // DI looks up a provider registered with the `OpaqueKey` `APP_CONFIG`
  constructor(@Inject(APP_CONFIG) private myConfig: any) {} 

  // DI looks up a provider registered with the object `APP_CONFIG_2`
  constructor(@Inject(APP_CONFIG_2) private myConfig: any) {} 

对象键 ( APP_CONFIG_2) 和OpaqueToken( APP_CONFIG) 必须是完全相同的实例。具有相同内容的不同实例将不起作用。这使得查找密钥声明的位置以及提供者和注入目标是否使用相同的密钥变得容易。

对于一个字符串,它可以是一个不同的实例,这带来了风险,即在不同的模块中使用相同的字符串值,并可能导致冲突或注入错误的提供程序。

于 2017-01-21T17:12:13.103 回答
4

什么是不透明令牌?它是干什么用的?

用于注入另一个同名提供者(服务)的不透明令牌。

这使您可以避免命名冲突。

     const MY_HTTP_TOKEN: OpaqueToken = new OpaqueToken('Http');

     providers: [
        { provide: MY_HTTP_TOKEN, useClass: Http }
     ]

     constructor(@Inject(MY_HTTP_TOKEN) private myHttpService){}

于 2017-01-22T09:41:15.570 回答
4

不透明令牌只是一个运行时类,用作注入器提供程序的唯一标识符。

假设您有一个值“secretId”,您想将其用于一些服务和组件。您不想在您的服务和组件中对此进行硬编码,因为它会在未来发生变化。您还想为您的服务和组件编写测试。

使用类,您可以将类用作实现、类型和注入器令牌。对于字符串值、其他文字表达式、对象等——您没有任何东西可用作注入器令牌。您可以使用字符串作为注入器令牌,但没有保证该字符串将是唯一的。使用不透明令牌,即使两个令牌具有相同的名称,它们也会被评估为不同的令牌。

于 2017-01-22T11:15:35.313 回答
2

我是 angular 2 的新手,但我想尝试解释我从https://blog.thoughtram.io/angular/2016/05/23/opaque-tokens-in-angular-2.html中理解的内容简单的代码。CMIIW。

...
const CONFIG_ONE = {title: 'My awesome app'};
let configOneToken = 'config';  //'config' is an example of string-type token

const CONFIG_TWO = {title: 'My fantastic app'};
let configTwoToken = 'config';

providers = [
  { provide: configOneToken, useValue: CONFIG_ONE },
  { provide: configTwoToken, useValue: CONFIG_TWO }
];

那段代码会有问题(后者会覆盖前者),因为它有冲突('config' == 'config')。在那个玩具代码中可能太明显且毫无意义,但在真实代码中,当在第三方库中定义提供者之一时,我们可能无法轻松识别这种冲突。因此,为了解决这个问题,我们可以使用 OpaqueToken,如下面的代码所示。

...
const CONFIG_ONE = {title: 'My awesome app'};
const OPAQUE_TOKEN_ONE = new OpaqueToken('config'); //this is an example of object-type token

const CONFIG_TWO = {title: 'My fantastic app'};
const OPAQUE_TOKEN_TWO = new OpaqueToken('config');

providers = [
  { provide: OPAQUE_TOKEN_ONE, useValue: CONFIG_ONE },
  { provide: OPAQUE_TOKEN_TWO, useValue: CONFIG_TWO }
];

任何同一类的两个实例永远不会相等(new OpaqueToken('config') != new OpaqueToken('config')),因此避免了冲突。它OpaqueToken本身只不过是一个简单的无所事事的类。

于 2017-01-22T10:18:43.423 回答