我有一个 Angular 项目,该项目使用的服务经常通过典型的创建/读取/更新/删除/读取所有条目列表进行重复。我也经常想在收到数据后以类似的方式对其进行操作。因此,我编写了使用 apply
的装饰器,它以由传递给它们的参数确定的方式“转换”数据(参数始终是对象类)。
正常使用时,如下所示:
//rule.service.ts
@Injectable({
providedIn: 'root'
})
export class RuleService {
rulesUrl: string = `${Constants.wikiApiUrl}/rule/`;
constructor(private http: HttpClient) {}
@TransformObservable(RuleObject)
getRule(pk: number): Observable<Rule>{
return this.http.get<Rule>(`${this.rulesUrl}/${pk}`);
}
}
这种情况经常发生,所以我想编写一个可以扩展的父服务:
//generic-object.service.ts
@Injectable({
providedIn: 'root'
})
export abstract class GenericObjectService{
baseUrl: string;
constructor(
private http: HttpClient,
public objectClass: any,
) {}
@TransformObservable(this.objectClass) //This line won't work
read(pk: number): Observable<any>{
return this.http.get(`${this.baseUrl}/${pk}`);
}
}
问题是我不能使用“this”作为装饰器参数,它在解析 IIRC 时不存在。但是有没有一种方法可以将装饰器参数以某种方式传递给我注入(inject)的服务,以便装饰器可以使用它?
下面还可以找到“TransformObservable”装饰器:
export function TransformObservable(modelClass: any){
/**Decorator to apply transformObservableContent */
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor){
const originalMethod = descriptor.value;
descriptor.value = function(){
const observable = originalMethod.apply(this, arguments);
return transformObservableContent(observable, modelClass);
}
return descriptor;
}
}
最佳答案
基于@S.D.我终于明白了他一直想表达的意思:你可以在放入descriptor.value的匿名函数中访问this
。因此,为了让我的装饰器能够正确执行此操作,我必须使用 this
从该匿名函数内部访问 modelClass
,然后我就可以开始了。以下是 S.D. 的解决方案:看起来像是付诸实践:
export function TransformObservable(modelClass: any){
/**Decorator to apply transformObservableContent */
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor){
const originalMethod = descriptor.value;
descriptor.value = function(){
const observable = originalMethod.apply(this, arguments);
//If the decorator argument was not a class but instead a property
// name of a property on the object that uses the decorator that
// contains the class, update the modelClass variable
const decoratorArgumentIsProperty = ["String", "string"].includes(typeof modelClass);
if(decoratorArgumentIsTargetProperty){
modelClass = this[modelClass];
}
return transformObservableContent(observable, modelClass);
}
return descriptor;
}
}
关于angular - 将变量传递给注入(inject)的服务以用作装饰器参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67146447/