Sha*_*ane 8 generics typescript angular
我正在尝试创建一个通用服务,它将获取一些远程数据并使用它创建一些对象.
@Injectable()
export class tService<T> {
private _data: BehaviorSubject<T[]> = new BehaviorSubject([]);
private url = '...url...'; // URL to web api
constructor(private http: HttpClient) {
this.http.get<T[]>(this.url).subscribe(theThings => {
theThings = _.map(theThings, (theThing) => new T(theThing));
this._data.next(theThings);
});
}
}
Run Code Online (Sandbox Code Playgroud)
这给了我错误T only refers to type, but is being used as a value here.好没关系.我明白发生了什么.我已经看到了几个问类似问题的问题.
例如:
似乎我在某个时候遇到过类中硬编码的任何解决方案,或者在某个地方添加了T的类构造函数.但我无法弄清楚该怎么做.我的问题是被实例化的类在构造函数中有参数,我使用的是Angular的DI系统,所以我不能(???)将parmeter添加到服务的构造函数中.
constructor(private playersService: gService<Player>, private alliesService: gService<Ally>) { }
Run Code Online (Sandbox Code Playgroud)
任何人都可以知道我应该在这做什么?另外,如果可能的话,我更愿意回答不是某种"黑客".如果可以选择做一些几乎无法读取的东西,只需复制和粘贴服务几次并更改它所引用的类,我将采用第二种方法.
类名既指类类型的 ,也指它的构造函数,这就是为什么你可以同时写let x: ClassName和new ClasName()。泛型参数只是一种类型(例如,很像接口),这就是编译器抱怨您将其用作值(预期的值是构造函数)的原因。您需要做的是传递一个额外的参数,该参数将作为以下对象的构造函数T:
export class tService<T> {
private _data: BehaviorSubject<T[]> = new BehaviorSubject<T>([]);
private url = '...url...'; // URL to web api
constructor(private http: HttpClient, ctor: new (data: Partial<T>)=> T) {
this.http.get<T[]>(this.url).subscribe(theThings => {
theThings = _.map(theThings, (theThing) => new ctor(theThing));
this._data.next(theThings);
});
}
}
//Usage
class MyClass {
constructor(p: Partial<MyClass>) {
// ...
}
}
new tService(http, MyClass)
Run Code Online (Sandbox Code Playgroud)
注意构造函数签名的参数可能会根据您的用例而有所不同。
编辑
您提到您不能向构造函数添加参数,当我们运行代码时,泛型(以及一般的所有类型)都会被删除,因此您不能T在运行时依赖于某个地方,有人必须传入类构造函数。您可以通过多种方式实现这一点,最简单的版本是为每个T实例创建专用的类,然后注入特定的类:
class tServiceForMyClass extends tService<MyClass> {
constructor(http: HttpClient) {
super(http, MyClass)
}
}
Run Code Online (Sandbox Code Playgroud)
init或者,您可以在需要构造函数作为参数的方法中依赖构造函数来完成工作:
export class tService<T> {
private _data: BehaviorSubject<T[]> = new BehaviorSubject<T>();
private url = '...url...'; // URL to web api
constructor(private http: HttpClient){}
init(ctor: new (data: Partial<T>)=> T) {
this.http.get<T[]>(this.url).subscribe(theThings => {
theThings = _.map(theThings, (theThing) => new ctor(theThing));
this._data.next(theThings);
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
239 次 |
| 最近记录: |