Angular 2 "No provider for String!"
Angular 2 "No provider for String!"
我正在尝试在 Angular 2 中创建通用数据服务,但我遇到了一个奇怪的错误。本质上,我正在创建一个 HTTP 服务,其方法采用 api url 的一部分,以便我可以将它用于多种情况。例如,我想传入 'projects/' 并将其与 'api/' 连接起来以获得 'api/projects/',然后我可以在 http 调用中使用它。
我现在的dataService.ts:
import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import 'rxjs/add/operator/map'
import { Observable } from 'rxjs/Observable';
import { Configuration } from '../app.constants';
@Injectable()
export class DataService {
private actionUrl: string;
private headers: Headers;
constructor(private _http: Http, private _configuration: Configuration, public action: string) {
this.actionUrl = _configuration.ApiUrl
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.headers.append('Accept', 'application/json');
}
public GetAll (action: string): Observable<any> {
return this._http.get(this.actionUrl + action).map((response: Response) => <any>response.json());
}
public GetSingle (action: string, id: number): Observable<Response> {
return this._http.get(this.actionUrl + action + id).map(res => res.json());
}
public Add (action: string, itemToAdd: any): Observable<Response> {
var toAdd = JSON.stringify(itemToAdd);
return this._http.post(this.actionUrl + action, toAdd, { headers: this.headers }).map(res => res.json());
}
public Update (action: string, id: number, itemToUpdate: any): Observable<Response> {
return this._http
.put(this.actionUrl + id, JSON.stringify(itemToUpdate), { headers: this.headers })
.map(res => res.json());
}
public Delete (action: string, id: number): Observable<Response> {
return this._http.delete(this.actionUrl + id);
}
}
我尝试使用 'projects' 作为参数调用 GetAll 的组件来自:
import { Component, OnInit } from '@angular/core';
import { DataService } from '../services/dataService';
@Component({
selector: 'project-detail',
templateUrl: 'app/project/project-detail.component.html'
})
export class ProjectDetailComponent implements OnInit{
projects: Object[];
constructor(private _dataService: DataService) {}
getProjects(): void {
this._dataService.GetAll('projects').subscribe(projects => this.projects = projects);
}
ngOnInit(): void {
this.getProjects();
}
}
我确实在 app.module.ts 中将服务添加为提供商。还有一件事需要注意,我在这里展示的组件是名为 HomeComponent 的组件的子组件,它位于 AppComponent 中。
这是 HomeComponent 的样子:
import { Component, OnInit } from '@angular/core';
import { ProjectDetailComponent } from '../project/project-detail.component';
@Component({
selector: 'home',
templateUrl: '<project-detail></project-detail>'
})
export class HomeComponent {}
错误:
EXCEPTION: Uncaught (in promise): Error: Error in app/home/home.component.html:2:0 caused by: No provider for String!
我知道它在抱怨我传递给 GetCall 的字符串,但我不知道为什么。
如有任何帮助,我们将不胜感激!
你不能随便注入东西。您尝试注入的任何内容都需要配置为可注入。在大多数情况下,这意味着只需将 class 添加到 providers
列表中。对于字符串,就没那么简单了。我们需要做一些事情。
- 首先我们需要创建一个令牌1
- 然后使用该标记配置要注入的字符串。
- 然后同理,
@Inject
把它变成目标。
import { OpaqueToken } from '@angular/core';
// 1. Create token
export const ACTION = new OpaqueToken('app.action');
// 2. Configure the `providers` (Maybe in the AppModule)
providers: [
{ provide: ACTION, useValue: 'the value you want'
]
import { Inject } from '@angular/core';
export class DataService {
// 3. Injection target
constructor(@Inject(ACTION) action: string) {}
}
1 - 请参阅 Dependency Injection Tokens
更新
现在,对于 Angular 4,我们应该使用 InjectionToken
而不是 OpaqueToken
我正在尝试在 Angular 2 中创建通用数据服务,但我遇到了一个奇怪的错误。本质上,我正在创建一个 HTTP 服务,其方法采用 api url 的一部分,以便我可以将它用于多种情况。例如,我想传入 'projects/' 并将其与 'api/' 连接起来以获得 'api/projects/',然后我可以在 http 调用中使用它。
我现在的dataService.ts:
import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import 'rxjs/add/operator/map'
import { Observable } from 'rxjs/Observable';
import { Configuration } from '../app.constants';
@Injectable()
export class DataService {
private actionUrl: string;
private headers: Headers;
constructor(private _http: Http, private _configuration: Configuration, public action: string) {
this.actionUrl = _configuration.ApiUrl
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.headers.append('Accept', 'application/json');
}
public GetAll (action: string): Observable<any> {
return this._http.get(this.actionUrl + action).map((response: Response) => <any>response.json());
}
public GetSingle (action: string, id: number): Observable<Response> {
return this._http.get(this.actionUrl + action + id).map(res => res.json());
}
public Add (action: string, itemToAdd: any): Observable<Response> {
var toAdd = JSON.stringify(itemToAdd);
return this._http.post(this.actionUrl + action, toAdd, { headers: this.headers }).map(res => res.json());
}
public Update (action: string, id: number, itemToUpdate: any): Observable<Response> {
return this._http
.put(this.actionUrl + id, JSON.stringify(itemToUpdate), { headers: this.headers })
.map(res => res.json());
}
public Delete (action: string, id: number): Observable<Response> {
return this._http.delete(this.actionUrl + id);
}
}
我尝试使用 'projects' 作为参数调用 GetAll 的组件来自:
import { Component, OnInit } from '@angular/core';
import { DataService } from '../services/dataService';
@Component({
selector: 'project-detail',
templateUrl: 'app/project/project-detail.component.html'
})
export class ProjectDetailComponent implements OnInit{
projects: Object[];
constructor(private _dataService: DataService) {}
getProjects(): void {
this._dataService.GetAll('projects').subscribe(projects => this.projects = projects);
}
ngOnInit(): void {
this.getProjects();
}
}
我确实在 app.module.ts 中将服务添加为提供商。还有一件事需要注意,我在这里展示的组件是名为 HomeComponent 的组件的子组件,它位于 AppComponent 中。
这是 HomeComponent 的样子:
import { Component, OnInit } from '@angular/core';
import { ProjectDetailComponent } from '../project/project-detail.component';
@Component({
selector: 'home',
templateUrl: '<project-detail></project-detail>'
})
export class HomeComponent {}
错误:
EXCEPTION: Uncaught (in promise): Error: Error in app/home/home.component.html:2:0 caused by: No provider for String!
我知道它在抱怨我传递给 GetCall 的字符串,但我不知道为什么。
如有任何帮助,我们将不胜感激!
你不能随便注入东西。您尝试注入的任何内容都需要配置为可注入。在大多数情况下,这意味着只需将 class 添加到 providers
列表中。对于字符串,就没那么简单了。我们需要做一些事情。
- 首先我们需要创建一个令牌1
- 然后使用该标记配置要注入的字符串。
- 然后同理,
@Inject
把它变成目标。
import { OpaqueToken } from '@angular/core';
// 1. Create token
export const ACTION = new OpaqueToken('app.action');
// 2. Configure the `providers` (Maybe in the AppModule)
providers: [
{ provide: ACTION, useValue: 'the value you want'
]
import { Inject } from '@angular/core';
export class DataService {
// 3. Injection target
constructor(@Inject(ACTION) action: string) {}
}
1 - 请参阅 Dependency Injection Tokens
更新
现在,对于 Angular 4,我们应该使用 InjectionToken
而不是 OpaqueToken