如何解决将变量传递给注入的服务以用作装饰器参数
我有一个 Angular 项目,它使用的服务经常以典型的创建/读取/更新/删除/读取所有条目列表重复。我也经常想在接收到数据后以类似的方式操作接收到的数据。所以我编写了使用 sink(receiveValue:)
的装饰器,它以传递给它们的参数确定的方式“转换”数据(参数始终是一个对象类)。
在正常使用中,这看起来像这样:
UserProfileviewmodel
这种情况经常发生,所以我想编写一个可以扩展的父服务:
apply
问题是我不能对装饰器参数使用“this”,它在解析 IIRC 时不存在。但是有没有办法以某种方式将装饰器参数传递给我注入的服务,以便装饰器可以使用它?
还可以在下面找到“TransformObservable”装饰器:
//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}`);
}
}
解决方法
this
关键字在函数作用域之外不可用。但是,您可以将所需的对象定义为同一类中的字段/属性,并且在装饰器注释中,您可以只传递装饰器函数将查找的字符串,或者传递实际的对象引用。
在装饰器中,检查传递给注解的参数:
if(typeof modelClass === 'string'){
// lookup a property in decorated class definition
modelClass = target[modelClass]; // or,this[modelClass]
}else {
// assume modelClass is the needed object
}
这将允许您使用:
@TransformObservable('propertyName');
// or
@TransformObservable(someObjectReference);
target
和 this
之间的区别:
传递给装饰器函数的target
是定义使用装饰器的类的对象。它将具有在类中定义的所有属性和方法,并可用于检索它们,如上所示。但是,target
不是您通常在类方法中使用的运行时 this
。它唯一的替换方法 (descriptor.value
) 将包含 this
,就像原始方法一样。
因此,如果您真的需要 this
而不仅仅是修饰类定义,您必须将所有代码内部移动到替换函数 descriptor.value
中。在那里您可以访问 this
以及传递给装饰器和装饰器工厂的所有参数。
基于@S.D. 's answer 我终于明白他一直想说的话:您可以访问您放入descriptor.value 的匿名函数内的this
。因此,为了让我的装饰器能够正确执行此操作,我必须使用 modelClass
从匿名函数内部访问 this
,我很高兴。这是 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;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。