Typescript通用服务 [英] Typescript generic service
问题描述
我对typescript和angular2 / 4很陌生,我正在构建一个包含Car和Driver两个基本实体的应用程序,我所做的就是使用API调用列出它们。
我面临的问题是每个CarService和DriverService都有代码冗余,并且我可能为其他实体服务使用相同的代码。
目前的实现跳过了其他的ilustration方法:
@Injectable()
导出class CarService {
private actionUrl:string;
私人标题:标题;
构造函数(private _http:Http,private _configuration:Configuration){
//获取API URL并指定根
this.actionUrl = _configuration.serverWithApiUrl + '汽车/';
this.headers = new Headers();
this.headers.append('Content-Type','application / json');
this.headers.append('Accept','application / json');
}
//函数获取所有Cars - API CALL:/
public GetAll =():Observable< Car []> => ($ response)=>< Car []> response.json())
.catch (this.handleError);
}
//通过特定id获取汽车的功能 - API CALL:/:id
public GetSingle =(id:number):Observable< Car> => {
return this._http.get(this.actionUrl + id)
.map((response:Response)=>< Car> response.json())
.catch( this.handleError);
}
//添加一个Car-API的函数CALL:/ create
public Add =(newCar:Car):Observable< Car> => {
return this._http.post(this.actionUrl +'/ create',JSON.stringify(newCar),{headers:this.headers})
.catch(this.handleError);
}
//更新Car-API的函数CALL:/
public Update =(id:number,CarToUpdate:Car):Observable< Car> => {
return this._http.put(this.actionUrl + id,JSON.stringify(CarToUpdate),{headers:this.headers})
.catch(this.handleError);
}
//删除Car-API的函数CALL:/:id
public Delete =(id:number):Observable< Response> => {
return this._http.delete(this.actionUrl + id)
.catch(this.handleError);
}
//抛出错误的函数
private handleError(error:Response){
console.error(error);
return Observable.throw(error.json()。error ||'Server error');
}
只有DriverService改变的是 Car / 在url的结尾处和数据类型在
Observable< Car []>
和响应中。
我想知道什么是避免使用泛型服务的最佳方法,以及如何在Typescript中执行此操作。
摘要class :
$ b
export抽象类AbstractRestService< T> {
构造函数(protected _http:Http,protected actionUrl:string){
}
getAll():Observable< T []> {
返回this._http.get(this.actionUrl).map(resp => resp.json()as T []);
}
getOne(id:number):Observable< T> {
return this._http.get(`$ {this.actionUrl} $ {id}`).map(resp => resp.json()as T);
驱动程序服务等级
@Injectable()
export class DriverService extends AbstractRestService< Driver> {
构造函数(http:Http,configuration:Configuration){
super(http,configuration.serverWithApiUrl +Driver /);
汽车服务等级
@Injectable()
导出类CarService扩展了AbstractRestService< Car> {
构造函数(http:Http,configuration:Configuration){
super(http,configuration.serverWithApiUrl +Car /);
$ / code> 请注意,只有具体的类被标记为 @Injectable()
,应该在模块内声明,而抽象的不应该。
I'm new to typescript and angular2/4 and I'm building a single app that have two basic entities which is Car and Driver and all I do is to list them with an API call.
The problem I'm facing is that I have code redundancy for each CarService and DriverService, and I might have the same code for other entities service.
The implementation is following so far, skipping other methods for ilustration :
@Injectable()
export class CarService {
private actionUrl: string;
private headers: Headers;
constructor(private _http: Http, private _configuration: Configuration) {
// Getting API URL and specify the root
this.actionUrl = _configuration.serverWithApiUrl + 'Car/';
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.headers.append('Accept', 'application/json');
}
// Function to get all Cars - API CALL: /
public GetAll = (): Observable<Car[]> => {
return this._http.get(this.actionUrl)
.map((response: Response) => <Car[]>response.json())
.catch(this.handleError);
}
// Function to get a Car by specific id - API CALL: /:id
public GetSingle = (id: number): Observable<Car> => {
return this._http.get(this.actionUrl + id)
.map((response: Response) => <Car>response.json())
.catch(this.handleError);
}
// Function to add a Car - API CALL: /create
public Add = (newCar: Car): Observable<Car> => {
return this._http.post(this.actionUrl + '/create', JSON.stringify(newCar), { headers: this.headers })
.catch(this.handleError);
}
// Function to update a Car - API CALL: /
public Update = (id: number, CarToUpdate: Car): Observable<Car> => {
return this._http.put(this.actionUrl + id, JSON.stringify(CarToUpdate), { headers: this.headers })
.catch(this.handleError);
}
// Function to delete a Car - API CALL: /:id
public Delete = (id: number): Observable<Response> => {
return this._http.delete(this.actionUrl + id)
.catch(this.handleError);
}
// Function to throw errors
private handleError(error: Response) {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
What only change with the DriverService is the Car/
at the end of the url and the data type in Observable<Car[]>
and the response.
I would like to know what is the best way to avoid this with a generic service and how to do it in Typescript.
解决方案 You can create an abstract generic class and two children class that inherits from it :
abstract class:
export abstract class AbstractRestService<T> {
constructor(protected _http: Http, protected actionUrl:string){
}
getAll():Observable<T[]> {
return this._http.get(this.actionUrl).map(resp=>resp.json() as T[]);
}
getOne(id:number):Observable<T> {
return this._http.get(`${this.actionUrl}${id}`).map(resp=>resp.json() as T);
}
}
driver service class
@Injectable()
export class DriverService extends AbstractRestService<Driver> {
constructor(http:Http,configuration:Configuration){
super(http,configuration.serverWithApiUrl+"Driver/");
}
}
car service class
@Injectable()
export class CarService extends AbstractRestService<Car> {
constructor(http:Http,configuration:Configuration) {
super(http,configuration.serverWithApiUrl+"Car/");
}
}
Note that only the concrete classes are marked as @Injectable()
and should be declared inside a module while the abstract one should not.
这篇关于Typescript通用服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!