[Angular 2] Understanding OpaqueToken

When using provider string tokens, there’s a chance they collide with other third-party tokens. Angular has with the concept of opaque tokens, that allow us to make whatever token we use unique, so we don’t run into collision problems. In this lesson we’ll explore how they work.

We created a value provide like this:

 providers: [
    TodoService,
    ConsoleService,
    TranslateService,
   ,{
        provide: LoggerProvider, useFactory: (cs, ts) => {
             return new LoggerProvider(cs, ts, true)
        },
        deps: [ConsoleService, TranslateService]
    }
   ,{
        provide: apiUrl,
        useValue: ‘http://localhost:3000/api‘
    }
],

It turns out that this can be problematic in case we‘re using, for example, a third-party library that comes with its own provider that introduces the same token.

third-party.ts:

export const THIRD_PARTY_PRIVODERS = [
  {
      provide: apiUrl,
      useValue: ‘someurl‘
  }
]

So when you inject third-pary library into our app.ts:

 providers: [
    TodoService,
    ConsoleService,
    TranslateService,
   ,{
        provide: LoggerProvider, useFactory: (cs, ts) => {
             return new LoggerProvider(cs, ts, true)
        },
        deps: [ConsoleService, TranslateService]
    }
   ,{
        provide: apiUrl,
        useValue: ‘http://localhost:3000/api‘
    }
   ,THIRD_PARTY_PROVIDERS
], 

Then it will rewrite our ‘apiUrl‘ because THIRD_PARTY_PROVIDERS comes behind apiUrl.

To solve this problem, Angular introduce OpaqueToken.

app.tokens.ts:

import {OpaqueToken} from ‘@angular/core‘;

export const API_URL = new OpaqueToken(‘apiUrl‘)

Now ‘API_URL‘ is a class instance not just a string, class instance is always unique.

Then in app.ts:

import {API_URL} from ‘./app.tokens‘ 

providers: [
    TodoService,
    ConsoleService,
    TranslateService,
   ,{
        provide: LoggerProvider, useFactory: (cs, ts) => {
             return new LoggerProvider(cs, ts, true)
        },
        deps: [ConsoleService, TranslateService]
    }
   ,{
        provide: API_URL,
        useValue: ‘http://localhost:3000/api‘
    }
   ,THIRD_PARTY_PROVIDERS
], 

In DataService:

import {LoggerProvider} from ‘./LoggerProvider‘;
import {Injectable} from ‘@angular/core‘;
import {Http} from ‘@angular/core‘;
import {Inject} from ‘@angular/core‘;
import {API_URL} from ‘./app.tokens‘;

@Injectable
export class TodoService{

    constructor(@Inject(API_URL) private apiUrl, private logger: LoggerProvider, private http: Http){ }

    getTodos(){
        this.logger.debug(‘Items‘, this.todos);
        return this.http.get(`${this.apiUrl}/todos`).map(res => res.json());
    }
}

Now we won‘t have conflict anymore.

As a general rule, always create opaque tokens when using string tokens for providers. For example:

third-party.ts:

import {OpaqueToken} from ‘@angular/core‘;

const API_URL = new OpaqueToken(‘apiUrl‘);
const CONFIG_URL = new OpaqueToken(‘configUrl‘);

export const THIRD_PARTY_PROVIDERS = [
  {
     provide: API_URL,
     useValue: ‘somevalue‘
  },
  {
     provide: CONFIG_URL,
     useValue: ‘somevalue‘
  }
]
时间: 2024-08-01 06:25:26

[Angular 2] Understanding OpaqueToken的相关文章

[Angular 2] Understanding Pure & Impure pipe

First, how to use a build in pipe: <div class="pipe-example"> <label>Uppercase Pipe: {{ message | uppercase }}</label> </div> <div class="pipe-example"> <label>Lowercase Pipe: {{ message | lowercase

来自 Thoughtram 的 Angular 2 系列资料

Angular 2 已经正式 Release 了,Thoughtram 已经发布了一系列的文档,对 Angular 2 的各个方面进行深入的阐释和说明. 我计划逐渐将这个系列翻译出来,以便对大家学习 Angular 2 提供一些方便. Getting Started Building a Zippy component in Angular 2 Developing a Tabs component in Angular 2 Angular 2 Template Syntax demystifi

angular default project (angular.json的解读)

Change the default Angular project Understanding it's purpose and limits Klaus KazlauskasFollow Nov 6, 2018 Angular's default project is nothing more than a string, set in angular.json, to say which project should run with ng commands without a defin

[Angular 2] 8. Understanding @Injectable

In order to resolve a dependency, Angular’s DI uses type annotations. To make sure these types are preserved when transpiled to ES5, TypeScript emits metadata. In this lesson we’ll explore how the @Injectable decorator ensures metadata generation for

AngularJs学习笔记--Understanding Angular Templates

原版地址:http://docs.angularjs.org/guide/dev_guide.mvc.understanding_model angular template是一个声明规范,与model.controller的信息一起,渲染成用户在浏览器中所看到的视图.它是静态的DOM,包括HTML.CSS.angular特别的元素和angular指定的元素属性.angular元素和属性指示angular去扩展行为以及将template DOM转换为动态视图的DOM. 下面是我们可以在templ

【转】Understanding the Angular Boot Process

原文: https://medium.com/@coderonfleek/understanding-the-angular-boot-process-9a338b06248c --------------------------------------------------------------------------------- For newcomers to Angular 2+ (now referred to simply as Angular), the struggle i

[Angular 2] BYPASSING PROVIDERS IN ANGULAR 2

Artical --> BYPASSING PROVIDERS IN ANGULAR 2 Here trying to solve one problem: On the left hand side of tree, there are 4 green blocks and 1 blue block. Meaning that three green dataService will use 'OtherProvider' which in an instance of DataService

[Angular 2] 7. Factory Provider with dependencies

This lesson discusses when and how to add dependencies, resolved by Angular’s DI, to factory providers. The example used in this lesson builts upon the previous lesson on understanding factory providers. For example, the LoggerProvider need to use Co

[Angular 2] Directive intro and exportAs

First, What is directive, what is the difference between component and directive. For my understanding, component is something like 'canvas', 'form', 'table'... they have the template and their own functionality. It defines how a html tag should work