angular - 将变量传递给注入(inject)的服务以用作装饰器参数

标签 angular inheritance decorator

我有一个 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/

相关文章:

Angular Material - 扁平树和嵌套树的区别

c# - 如何在 mvc .net 上使用没有 "action is ambiguous"的基本 Controller 的 Action ?

typescript - 如何为 descriptor.value 分配一个新函数?

c++ - 在不浪费内存的情况下扩充数据结构

python:用默认的kwargs装饰函数

django - 与装饰器和正常功能相同的条件?

angular - 如何解决 Angular CLI 错误 : Cannot find module 'ansi-colors' ?

javascript - 如何在不相关的组件之间共享数据? Angular 6

javascript - 更改路由时,更改 ngOnInit 中的元素不起作用,但能够访问元素

C# 基础继承