ES5和ES6中的角2依赖注入 [英] Angular 2 dependency injection in ES5 and ES6

查看:178
本文介绍了ES5和ES6中的角2依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个基本的TypeScript / ES.next示例,它使用装饰器DI和遵循框架手册建议的语法:

  import {Component,Inject,Injectable,NgModule,OpaqueToken} from'@ angular /核心';来自'@ angular / platform-b​​rowser'的
import {BrowserModule};
import {platformBrowserDynamic} from'@ angular / platform-b​​rowser-dynamic';

const CONSTANT = {value:'constant'};
const CONSTANT_TOKEN = new OpaqueToken;
const CONSTANT_PROVIDER = {提供:CONSTANT_TOKEN,useValue:CONSTANT};

@Injectable()
class Service {
constructor(@Inject(CONSTANT_TOKEN)constant){
console.log('Service constructor',constant);
}
}

@Component({
selector:'app',
template:'...',
providers: [Service,CONSTANT_PROVIDER]
})
class AppComponent {
constructor(@Inject(Service)service:Service,@Inject(CONSTANT_TOKEN)constant){
console.log AppComponent构造函数,服务,常量);
}


@NgModule({
imports:[BrowserModule],
声明:[AppComponent],
bootstrap:[AppComponent ]
})
class AppModule {}

platformBrowserDynamic()。bootstrapModule(AppModule);

如何在ES5中写入?

ES6 / ES2015?



如何可注入注入在这些情况下翻译的装饰器?



该问题特别适用于真实世界的ES6浏览器具有类但可以使用的实现需要 System.import 而不是ES6导入。

解决方案

可注入 decorator是特定于Angular 2的TypeScript风格。它使类构造函数能够隐式通过TypeScript类型注释注释为DI。它在TS中是冗余的,并且在JS中不需要注入注释的依赖关系,注释为 Inject



Angular 2 injectables类和构造函数)应该使用注释参数注释静态属性。



注释是一个数组,包含 new ed可注册类的装饰器:

  function SomeComponent(...){} 
SomeComponent.annotations = [new Componenent(...)] ;

参数是一个数组,包含构造函数参数,每个元素都是一个数组,它包含一个列表,用于各个构造函数属性的 new ed装饰符(类似于 $ inject Angular 1.x中的属性显式注释):

  function Service(someService,anotherService){} 
服务。 parameters = [
[new Inject(SomeService)],
[new Inject(AnotherService),new可选,新的SkipSelf]
];

所有类装饰器都从 TypeDecorator ,这意味着它们可以被称为函数。在这种情况下,使用所谓的DSL语法,可以使用 帮助函数

  var SomeComponent = Componenent(...)。Class(...); 

Class 也可单独使用,来自给定定义对象的新课程,并允许使用数组注释构造函数方法(类似于Angular 1.x中的内联数组显式注释):

  var SomeService = Class({
constructor:[[new Inject(SomeService)],function(someService){}]
});

这是如何 ES6 with System.import 可能如下所示:

  Promise.all([
System.import('@ angular / core'),
System.import('@ angular / platform-b​​rowser'),
System.import('@ angular / platform-b​​rowser-dynamic')
])
.then(([
{Component,Inject,Injectable,Optional,NgModule,OpaqueToken}
{BrowserModule},
{platformBrowserDynamic}
])=> {

const CONSTANT = {value:'constant'};
const CONSTANT_TOKEN = new OpaqueToken;
const CONSTANT_PROVIDER = {提供:CONSTANT_TOKEN,useValue:CONSTANT};

类服务{
构造函数(常量){}
}
Service.parameters = [[new Inject(CONSTANT_TOKEN)]];

class AppComponent {
构造函数(服务,常量){}
}
AppComponent.annotations = [new Component({
selector:'app',
template:'...',
providers:[Service,CONSTANT_PROVIDER]
})];
AppComponent.parameters = [[new Inject(Service)],[new Inject(CONSTANT_TOKEN)]];

class AppModule {}
AppModule.annotations = [new NgModule({
imports:[BrowserModule],
声明:[AppComponent],
bootstrap :[AppComponent]
})];

platformBrowserDynamic()。bootstrapModule(AppModule);

})
.catch((err)=> console.error(err));

这是如何 ES5与UMD模块和 ng 全球可能如下所示:

  var Class = ng.core.Class; 
var Component = ng.core.Component;
var Inject = ng.core.Inject;
var Injectable = ng.core.Injectable;
var NgModule = ng.core.NgModule;
var OpaqueToken = ng.core.OpaqueToken;

var BrowserModule = ng.platformBrowser.BrowserModule;
var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic;

var CONSTANT = {value:'constant'};
var CONSTANT_TOKEN = new OpaqueToken;
var CONSTANT_PROVIDER = {provide:CONSTANT_TOKEN,useValue:CONSTANT};

//使用A1风格的内联数组DI注释
//并创建一个注释构造函数的类助手函数
var Service = Class({
constructor:[ [new Inject(CONSTANT_TOKEN)],function(constant){
console.log('Service constructor',constant);
}]
});
//也可以是
// function Service(constant){};
// Service.parameters = [[new Inject(...)],...];

//当不是`new`ed时,组件是一个具有类助手方法的可链接工厂
var AppComponent = Component({
selector:'app',
template:'...',
providers:[Service,CONSTANT_PROVIDER]
})
.Class({
constructor:[
[new Inject服务)],
[new Inject(CONSTANT_TOKEN)],
函数(服务,常量){
console.log('AppComponent constructor',service,constant);
}
]
});
//也可以是
//函数AppComponent(...){};
// AppComponent.annotations = [new Component(...)];
// AppComponent.parameters = [[new Inject(...)],...];

var AppModule = NgModule({
imports:[BrowserModule],
声明:[AppComponent],
bootstrap:[AppComponent]
})
.Class({constructor:function(){}});
//也可以是
//函数AppModule(){};
// AppModule.annotations = [new NgModule(...)];

platformBrowserDynamic()。bootstrapModule(AppModule);


Here is a basic TypeScript/ES.next example that uses decorators for DI and follows the syntax suggested by the framework manual:

import {Component, Inject, Injectable, NgModule, OpaqueToken} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

const CONSTANT = { value: 'constant' };
const CONSTANT_TOKEN = new OpaqueToken;
const CONSTANT_PROVIDER = { provide: CONSTANT_TOKEN, useValue: CONSTANT };

@Injectable()
class Service {
  constructor(@Inject(CONSTANT_TOKEN) constant) {
    console.log('Service constructor', constant);
  }
}

@Component({
  selector: 'app',
  template: '...',
  providers: [Service, CONSTANT_PROVIDER]
})
class AppComponent {
  constructor(@Inject(Service) service: Service, @Inject(CONSTANT_TOKEN) constant) {
    console.log('AppComponent constructor', service, constant);    
  }
}

@NgModule({
  imports: [BrowserModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
class AppModule {}

platformBrowserDynamic().bootstrapModule(AppModule);

How would it be written in in ES5?

How would the same thing be done in untranspiled ES6/ES2015?

How are Injectable and Inject decorators translated in these cases?

The question particularly applies to real-world ES6 browser implementations that have classes but may use require or System.import instead of ES6 imports.

解决方案

Injectable decorator is specific to TypeScript flavour of Angular 2. It enables a class constructor to be implicitly annotated for DI through TypeScript type annotations. It is redundant in TS and unneeded in JS for injected dependencies that are annotated with Inject.

Angular 2 injectables (classes and constructor functions) are supposed to be annotated with annotations and parameters static properties under the hood.

annotations is an array that contains newed decorators for injectable class:

function SomeComponent(...) {}
SomeComponent.annotations = [new Componenent(...)];

parameters is an array that contains decorators for constructor parameters, each element is an array that contains a list of newed decorators for respective constructor property (similarly to $inject property explicit annotation in Angular 1.x):

function Service(someService, anotherService) {}
Service.parameters = [
  [new Inject(SomeService)],
  [new Inject(AnotherService), new Optional, new SkipSelf]
];

All class decorators are extended from TypeDecorator, meaning that they can be called as functions. In this case so-called DSL syntax is used that allows to chain a decorator with Class helper function:

var SomeComponent = Componenent(...).Class(...);

Class is also available separately, it constructs a new class from given definition object and allows to annotate constructor method with array (similarly to inline array explicit annotation in Angular 1.x):

var SomeService = Class({
  constructor: [[new Inject(SomeService)], function (someService) {}]
});

This is how ES6 with System.import may look like:

Promise.all([
  System.import('@angular/core'),
  System.import('@angular/platform-browser'),
  System.import('@angular/platform-browser-dynamic')
])
.then(([
  {Component, Inject, Injectable, Optional, NgModule, OpaqueToken},
  {BrowserModule},
  {platformBrowserDynamic}
]) => {

  const CONSTANT = { value: 'constant' };
  const CONSTANT_TOKEN = new OpaqueToken;
  const CONSTANT_PROVIDER = { provide: CONSTANT_TOKEN, useValue: CONSTANT };

  class Service {
    constructor(constant) {}
  }
  Service.parameters = [[new Inject(CONSTANT_TOKEN)]];

  class AppComponent {
    constructor(service, constant) {}
  }
  AppComponent.annotations = [new Component({
    selector: 'app',
    template: '...',
    providers: [Service, CONSTANT_PROVIDER]
  })];
  AppComponent.parameters = [[new Inject(Service)], [new Inject(CONSTANT_TOKEN)]];

  class AppModule {}
  AppModule.annotations = [new NgModule({
    imports: [BrowserModule],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
  })];

  platformBrowserDynamic().bootstrapModule(AppModule);

})
.catch((err) => console.error(err));

This is how ES5 with UMD modules and ng global may look like:

var Class = ng.core.Class;
var Component = ng.core.Component;
var Inject = ng.core.Inject;
var Injectable = ng.core.Injectable;
var NgModule = ng.core.NgModule;
var OpaqueToken = ng.core.OpaqueToken;

var BrowserModule = ng.platformBrowser.BrowserModule;
var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic;

var CONSTANT = { value: 'constant' };
var CONSTANT_TOKEN = new OpaqueToken;
var CONSTANT_PROVIDER = { provide: CONSTANT_TOKEN, useValue: CONSTANT };

// Class helper function that uses A1-flavoured inline array DI annotations
// and creates an annotated constructor
var Service = Class({
  constructor: [[new Inject(CONSTANT_TOKEN)], function (constant) {
    console.log('Service constructor', constant);
  }]
});
// can also be
// function Service(constant) {};
// Service.parameters = [[new Inject(...)], ...];

// when not being `new`ed, Component is a chainable factory that has Class helper method
var AppComponent = Component({
  selector: 'app', 
  template: '...',
  providers: [Service, CONSTANT_PROVIDER]
})
.Class({
  constructor: [
    [new Inject(Service)],
    [new Inject(CONSTANT_TOKEN)],
    function (service, constant) {
      console.log('AppComponent constructor', service, constant);
    }
  ]
});
// can also be
// function AppComponent(...) {};
// AppComponent.annotations = [new Component(...)];
// AppComponent.parameters = [[new Inject(...)], ...];

var AppModule = NgModule({
  imports: [BrowserModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
.Class({ constructor: function () {} });
// can also be
// function AppModule() {};
// AppModule.annotations = [new NgModule(...)];

platformBrowserDynamic().bootstrapModule(AppModule);

这篇关于ES5和ES6中的角2依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆