Angular 2 - Как передать параметры в абстрактный сервис
Angular 2 - Как передать параметры абстрактному сервису, когда я предоставляю сервис в модуле
Файл с абстрактным сервисом
@Injectable()
export class Service<T>{
private headers: RequestOptions = headersRequest.options;
private readonly baseUrl: string;
constructor(private http: Http, baseUrl: string) {
this.baseUrl = baseUrl;
}
public getAll(): Promise<T[]> {
return this.http.get(`${this.baseUrl}`)
.toPromise()
.then(this.extractData)
.catch(this.handleError);
}
public get(id: number): Promise<T> {
return this.http.get(`${this.baseUrl}`)
.toPromise()
.then(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body || {};
}
private handleError(error: Response | any) {
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Promise.reject(errMsg);
}
}
Файл с модулем, когда я предоставляю услугу
@NgModule({
imports: [
SharedModule,
RouterModule.forChild(routes)
],
declarations: [
HeaderTennisComponent,
TennisComponent,
ProgramsComponent,
ProgramComponent,
PlotsComponent,
GuidesComponent,
CategoriesComponent,
ChampionsComponent
],
providers: [Service]
})
Файл с компонентом, когда я использую сервис.
export class ProgramComponent implements OnInit {
private program: IProgram;
constructor(private route: ActivatedRoute, private tennisService: Service<IProgram>) {
//
}
public ngOnInit() {
this.getProgram(+this.route.snapshot.params['id']);
}
private getProgram(id: number) {
this.tennisService.get(id).then(
(program) => this.program = program
);
}
}
Мне нужно передать baseUrl, когда я предоставляю услугу.
1 ответ
Angular DI не имеет прямой поддержки генериков.
Есть несколько способов обойти это, в зависимости от ваших требований:
providers: [
{provide: 'baseUrl': useValue: 'http://example.com'},
{provide: Service, useFactory: (http, baseUrl) new Service<IProgram>(http, baseUrl), deps: [Http, new Inject('baseUrl') },
{provide: 'ServiceIProgram', useFactory: (http, baseUrl) new Service<IProgram>(http, baseUrl), deps: [Http, new Inject('baseUrl') },
{provide: 'Service', useFactory: (http, baseUrl) => (T) => new Service<T>(http, baseUrl), deps: [Http, new Inject('baseUrl')]
]
@Injectable()
export class Service<T>{
...
constructor(private http: Http, @Inject('baseUrl') baseUrl: string ) {
this.baseUrl = baseUrl;
}
export class ProgramComponent implements OnInit {
...
constructor(private route: ActivatedRoute,
@Inject(Service) private tennisService: Service<IProgram>, // fixed type parameter
@Inject('ServiceIProgram') private tennisService: Service<IProgram>,
@Inject('Service') serviceFactory:any // factory to instantiate yourself
) {
// not sure if passing generic type parameters this way is supported by TypeScript
this.tennisService = serviceFactory(IProgram);
}