如何将 Angular2 Http 服务注入 es6/7 Class?
How to Inject Angular2 Http service into es6/7 Class?
如果我使用 es6/7(babel - 第 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');
}
}
我试过:
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);
}
}
除第一个之外的所有编译。其他人允许我访问 Http class 或 http 实例。但是 none 有效。
我试图关注 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];
它现在编译但产生以下错误:
Uncaught (in promise) NoBindingError {message: "No provider for Http!
(Login -> Http)", stack: "Error: DI Exception↵ at
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: "No provider for Http!
(Login -> Http)"stack: "Error: DI Exception↵ at
NoBindingError.BaseException [as constructor]
(http://localhost:3000/bundle.js:8400:24)↵ at
NoBindingError.AbstractBindingError [as constructor]
(http://localhost:3000/bundle.js:9066:17)↵ at new NoBindingError
(http://localhost:3000/bundle.js:9102:17)↵ at Injector._throwOrNull
(http://localhost:3000/bundle.js:7469:20)↵ at
Injector._getByKeyDefault (http://localhost:3000/bundle.js:7516:22)↵
at Injector._getByKey (http://localhost:3000/bundle.js:7461:26)↵ at
Injector._getByDependency (http://localhost:3000/bundle.js:7447:26)↵
at Injector._instantiate (http://localhost:3000/bundle.js:7339:37)↵
at Injector._instantiateBinding
(http://localhost:3000/bundle.js:7330:26)↵ at Injector._new
(http://localhost:3000/bundle.js:7319:22)"proto: __
我已经回答了,如果你用ES7写代码,使用static getter for 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
}
我认为这是目前最简洁的方法。
请记住,目前还没有在 ES7 中支持参数装饰器的提案(例如 see this issue for Babel)。
官方API Review的方法对我有用:
import {Http, HTTP_PROVIDERS} from 'angular2/http';
@Component({
selector: 'http-app',
viewProviders: [HTTP_PROVIDERS],
templateUrl: 'people.html'
})
class PeopleComponent {
constructor(http: Http) {
http.get('people.json')
.map(res => res.json())
.subscribe(people => this.people = people);
}
}
因为您在 Babel 中启用了 @Decorators
...我将 fine-tune 这个答案与您的特定设置一起使用。
1.你错过了 HTTP_PROVIDERS
HTTP_PROVIDERS 常量包括处理 HTTP requests/responses 所需的许多函数。
import {Http, HTTP_PROVIDERS} from 'angular2/http';
@Component({
selector: 'login',
providers: [ HTTP_PROVIDERS ]
})
2。您需要对 DI(依赖注入)语法进行脱糖
如所述。
删除静态类型
constructor(http) {
@Inject 隐式处理 DI 但仅在 Angular2+Typescript 中受支持。由于您使用的是 Angular2+ES6,因此您需要将静态 getter 参数附加到您的 class 以提供特定于 ES6 的等价物。
static get parameters() {
return [[Http]];
}
3。您需要将 Http 实例绑定到构造函数中的 class
通过这样做,它将可以在您的 authenticate()
方法中访问。
constructor(http) {
this.http = http;
console.log('http', this.http);
}
...以及完整的实现:
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');
}
}
旁白:我知道这是有效的,因为我将它用于 EvanPlaice.com.
上的 <ng2-markdown>
组件
使用 babel-plugin-angular2-annotations,您可以像 TypeScript 一样使用构造函数参数类型注释注入服务。
安装 babel 插件:
npm install -D babel-plugin-angular2-annotations babel-plugin-transform-decorators-legacy babel-plugin-transform-class-properties babel-plugin-transform-flow-strip-types babel-preset-es2015
.babelrc:
{
"plugins": [
"angular2-annotations",
"transform-decorators-legacy",
"transform-class-properties",
"transform-flow-strip-types"
],
"presets": [
"es2015"
]
}
瞧!
import {Component, 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(http: Http) {
console.log('http', http);
this.http = http;
}
authenticate(username, password) {
this.http.get('/login');
}
}
请注意,类型签名仅用于依赖注入的提示,不用于类型检查。
如果我使用 es6/7(babel - 第 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');
}
}
我试过:
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);
}
}
除第一个之外的所有编译。其他人允许我访问 Http class 或 http 实例。但是 none 有效。
我试图关注 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];
它现在编译但产生以下错误:
Uncaught (in promise) NoBindingError {message: "No provider for Http! (Login -> Http)", stack: "Error: DI Exception↵ at 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: "No provider for Http! (Login -> Http)"stack: "Error: DI Exception↵ at NoBindingError.BaseException [as constructor] (http://localhost:3000/bundle.js:8400:24)↵ at NoBindingError.AbstractBindingError [as constructor] (http://localhost:3000/bundle.js:9066:17)↵ at new NoBindingError (http://localhost:3000/bundle.js:9102:17)↵ at Injector._throwOrNull (http://localhost:3000/bundle.js:7469:20)↵ at Injector._getByKeyDefault (http://localhost:3000/bundle.js:7516:22)↵
at Injector._getByKey (http://localhost:3000/bundle.js:7461:26)↵ at Injector._getByDependency (http://localhost:3000/bundle.js:7447:26)↵
at Injector._instantiate (http://localhost:3000/bundle.js:7339:37)↵
at Injector._instantiateBinding (http://localhost:3000/bundle.js:7330:26)↵ at Injector._new (http://localhost:3000/bundle.js:7319:22)"proto: __
我已经回答了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
}
我认为这是目前最简洁的方法。
请记住,目前还没有在 ES7 中支持参数装饰器的提案(例如 see this issue for Babel)。
官方API Review的方法对我有用:
import {Http, HTTP_PROVIDERS} from 'angular2/http';
@Component({
selector: 'http-app',
viewProviders: [HTTP_PROVIDERS],
templateUrl: 'people.html'
})
class PeopleComponent {
constructor(http: Http) {
http.get('people.json')
.map(res => res.json())
.subscribe(people => this.people = people);
}
}
因为您在 Babel 中启用了 @Decorators
...我将 fine-tune 这个答案与您的特定设置一起使用。
1.你错过了 HTTP_PROVIDERS
HTTP_PROVIDERS 常量包括处理 HTTP requests/responses 所需的许多函数。
import {Http, HTTP_PROVIDERS} from 'angular2/http';
@Component({
selector: 'login',
providers: [ HTTP_PROVIDERS ]
})
2。您需要对 DI(依赖注入)语法进行脱糖
如
删除静态类型
constructor(http) {
@Inject 隐式处理 DI 但仅在 Angular2+Typescript 中受支持。由于您使用的是 Angular2+ES6,因此您需要将静态 getter 参数附加到您的 class 以提供特定于 ES6 的等价物。
static get parameters() {
return [[Http]];
}
3。您需要将 Http 实例绑定到构造函数中的 class
通过这样做,它将可以在您的 authenticate()
方法中访问。
constructor(http) {
this.http = http;
console.log('http', this.http);
}
...以及完整的实现:
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');
}
}
旁白:我知道这是有效的,因为我将它用于 EvanPlaice.com.
上的<ng2-markdown>
组件
使用 babel-plugin-angular2-annotations,您可以像 TypeScript 一样使用构造函数参数类型注释注入服务。
安装 babel 插件:
npm install -D babel-plugin-angular2-annotations babel-plugin-transform-decorators-legacy babel-plugin-transform-class-properties babel-plugin-transform-flow-strip-types babel-preset-es2015
.babelrc:
{
"plugins": [
"angular2-annotations",
"transform-decorators-legacy",
"transform-class-properties",
"transform-flow-strip-types"
],
"presets": [
"es2015"
]
}
瞧!
import {Component, 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(http: Http) {
console.log('http', http);
this.http = http;
}
authenticate(username, password) {
this.http.get('/login');
}
}
请注意,类型签名仅用于依赖注入的提示,不用于类型检查。