【发布时间】:2018-04-05 05:41:57
【问题描述】:
我正在尝试创建一个通用服务,该服务将获取一些远程数据并使用它创建一些对象。
@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);
});
}
}
这给了我错误T only refers to type, but is being used as a value here。好没问题。我明白发生了什么。我看到有几个问题询问类似的问题。
例如:
- How to create a new object from type parameter in generic class in typescript?
- TypeScript return object constructed form generic
- Get constructor/instance from generic type in TypeScript
似乎我遇到的任何解决方案要么在某个时候在类中使用硬编码,要么在某处添加 T 的类构造函数。但我不知道该怎么做。我的问题是被实例化的类在构造函数中有参数,而我使用的是 Angular 的 DI 系统,所以我不能(???)向服务的构造函数添加参数。
constructor(private playersService: gService<Player>, private alliesService: gService<Ally>) { }
谁能弄清楚我应该在这里做什么?另外,如果可能的话,我希望答案不是某种“黑客”。如果它在做一些几乎不可读的事情和只是复制和粘贴服务几次和更改它所指的类之间做出选择,我会采取第二种选择。
【问题讨论】:
-
传递构造函数 is 是正确的方法,但你说得对,用 Angular 的 DI 抽象来做这件事很尴尬(尽管很有可能)。您是否考虑过用泛型方法替换泛型类?
-
@AluanHaddad 不是真的,那会是什么样子?
-
点赞
class S { get<T>(C: new (x: Thing) => T): Promise<T> {...} }。但是我现在看到您正在使用构造函数本身来触发异步进程的初始化,然后更改应用程序级别的状态。也就是说,您的服务正在作为被需要它的东西注入(并因此实例化)的服务的副作用...... -
@AluanHaddad 嗯,是的,可能不应该在构造函数中做异步的事情。从字里行间看,我认为您是在说我犯了几个导致我的问题的设计错误?
-
嗯...是的,我建议您可能有。很难说,因为您可能有一个我没有考虑过的用例。令我恼火的是,如果为与它一起使用的每个不同类型参数创建了一个实例,则通用参数仅在服务类上才有意义。是单例还是应用中有多个实例?
标签: angular typescript generics