zoukankan      html  css  js  c++  java
  • [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'
      }
    ]
  • 相关阅读:
    【css】所有的a标签设置为新窗口打开【原创】
    TP 3.1版本不支持 CONTROLLER_NAME
    关于TP 特殊页面伪静态规则的编写 研究实现
    larave PHP框架
    [转]git和github
    [转]mysql语句大全
    camera.swf?  提示  图片上传中请稍候,没任何报错
    mysql大小写敏感(默认为1,不敏感)
    数据cube的schema与sql的对应的关系
    MDX的实例讲解(排名前15的小例子)
  • 原文地址:https://www.cnblogs.com/Answer1215/p/5880257.html
Copyright © 2011-2022 走看看