如何将Angular2 Http服务注入es6/7类?

rob*_*cks 12 javascript babeljs angular

如果我使用es6/7(babel - stage 1)而不是TypeScript,那么如何注入服务,特别是Http?

这是我的组件JS:

import {Component, Inject, View, CORE_DIRECTIVES, ViewEncapsulation} from 'angular2/angular2';
import {Http} from 'angular2/http';

@Component({
  selector: 'login'
})
@View({
  templateUrl: './components/login/login.html',
  styleUrls: ['components/login/login.css'],
  directives: [CORE_DIRECTIVES],
  encapsulation: ViewEncapsulation.Emulated
})
export class Login {
  constructor(@Inject(Http) http) {
    console.log('http', http);
  }

  authenticate(username, password) {
    // this.http.get('/login');
  }
}
Run Code Online (Sandbox Code Playgroud)

我试过了:

export class Login {
  constructor(@Inject(Http) http) {
    console.log('http', http);
  }
}
/********************/
@Inject(Http)
export class Login {
  constructor(http) {
    console.log('http', http);
  }
}
/********************/
export class Login {
  constructor(Http: http) {
    console.log('http', http);
  }
}
/********************/
export class Login {
  constructor(http = Http) {
    console.log('http', http);
  }
}
/********************/
export class Login {
  constructor(Http) {
    this.http = new Http()
    console.log('http', this.http);
  }
}
/********************/
export class Login {
  constructor(http = new Http()) {
    console.log('http', http);
  }
}
Run Code Online (Sandbox Code Playgroud)

除了第一次编译之外的所有内容 其他人让我可以访问Http类或http实例.但都没有效果.

我试着按照Eric Martinez在评论中引用的讨论.Login.js现在:

import {Component, Inject, View, CORE_DIRECTIVES, ViewEncapsulation} from 'angular2/angular2';
import {HTTP_BINDINGS, Http, BaseRequestOptions, RequestOptions, RequestMethods} from 'angular2/http';

@Component({
  selector: 'login'
})
@View({
  templateUrl: './components/login/login.html',
  styleUrls: ['components/login/login.css'],
  directives: [CORE_DIRECTIVES],
  encapsulation: ViewEncapsulation.Emulated,
  bindings: [Http]
})
export class Login {

  constructor(http) {
    this.http = http;
    console.log('http', http);
  }

  authenticate(usernameEl, passwordEl) {
    var username = usernameEl.value;
    var password = passwordEl.value;
    console.log('username', username, password);

    // this.http.get('/login');
  }
}

Login.parameters = [Http];
Run Code Online (Sandbox Code Playgroud)

它现在编译但生成以下错误:

未捕获(在承诺中)NoBindingError {消息:"没有Http的提供者!(登录 - > Http)",堆栈:"错误:DI异常↵在NoBindingError.BaseExce ... or._new(http:// localhost:3000/bundle. js:7319:22)",keys:Array [2],injectors:Array [2]} constructResolvingMessage :( keys)arguments:(...)caller:(...)length:1name:""prototype:Object__proto__ :()context:(...)injectors:Array [2] 0:Injector1:Injectorlength:2__proto__:Array [0] keys:Array [2] message:"没有Http的提供者!(登录 - > Http)"堆栈:"错误:DI异常↵在NoBindingError.BaseException [作为构造函数](http:// localhost:3000/bundle.js:8400:24)↵在NoBindingError.AbstractBindingError [作为构造函数](http:// localhost:3000/bundle.js:9066:17 )↵新的NoBindingError(http:// localhost:3000/bundle.js:9102:17)↵在Injector._throwOrNull(http:// localhost:3000/bundle.js:7469:20)↵在Injector._getByKeyDefault(http:// localhost: 3000/bundle.js:7516:22)↵
在Injector._getByKey(http:// localhost:3000/bundle.js:7461:26)↵在Injector._getByDependency(http:// localhost:3000/bundle.js: 7447:26)↵
在Injector._instantiate(http:// localhost:3000/bundle.js:7339:37)↵
在Injector._instantiateBinding(http:// localhost:3000/bundle.js:7330:26)↵at Injector._new(http:// localhost:3000/bundle.js:7319:22)" proto:__

Eva*_*ice 13

因为你已经@Decorators启用了Babel

...我会根据您的具体设置微调这个答案.

1.你缺少HTTP_PROVIDERS

HTTP_PROVIDERS常量包括处理HTTP请求/响应所需的许多函数.

import {Http, HTTP_PROVIDERS} from 'angular2/http';    

@Component({
  selector: 'login',
  providers: [ HTTP_PROVIDERS ]
})
Run Code Online (Sandbox Code Playgroud)

2.你需要去掉DI(依赖注入)语法

正如@alexpods的回答中提到的那样.

删除静态类型

constructor(http) {
Run Code Online (Sandbox Code Playgroud)

@Inject隐式处理DI,但仅在Angular2 + Typescript中受支持.由于您使用的是Angular2 + ES6,因此需要在类中附加静态getter参数以提供ES6特定的等效项.

static get parameters() {
    return [[Http]];
}
Run Code Online (Sandbox Code Playgroud)

3.您需要在构造函数中将Http实例绑定到您的类

通过这样做,它将在您的authenticate()方法中可访问.

constructor(http) {
    this.http = http;
    console.log('http', this.http);
}
Run Code Online (Sandbox Code Playgroud)

......以及完整的实施:

import {Component, Inject, View, CORE_DIRECTIVES, ViewEncapsulation} from 'angular2/angular2';
import {Http, HTTP_PROVIDERS} from 'angular2/http';

@Component({
  selector: 'login',
  // required for Http
  providers: [ HTTP_PROVIDERS ]
})
@View({
  templateUrl: './components/login/login.html',
  styleUrls: ['components/login/login.css'],
  directives: [CORE_DIRECTIVES],
  encapsulation: ViewEncapsulation.Emulated
})
export class Login {
  constructor(http) {
    // bind http to your class during construction
    //   so it's available to authenticate()
    this.http = http;
  }

  // Angular2 DI desugar'd
  static get parameters() {
    return [[Http]];
  }

  authenticate(username, password) {
    this.http.get('/login');
  }
}
Run Code Online (Sandbox Code Playgroud)

旁白:我知道这是有效的,因为我将它用于EvanPlaice.com<ng2-markdown>上的组件.


ale*_*ods 9

我在这里已经回答了这个问题,如果您在ES7中编写代码,请使用静态getter parameters属性来指定constructor组件的注入.例如:

import { Http } from 'angular2/http';
// other imports ...

// component decorators ...
export class Login {

  static get parameters() {
    return [[Http]];
  }

  constructor(http) {
    this.http = http;
    console.log('http', http);
  }

  // other methods
}
Run Code Online (Sandbox Code Playgroud)

我觉得这个时候最简洁的方法.

请记住,目前没有提议在ES7中支持参数装饰器(例如,请参阅Babel的这个问题).