作者:聂依依mma | 来源:互联网 | 2022-12-09 19:16
我创建了一个自定义管道,可以从API检索文本内容,如下所示:
@Pipe({ name: 'apiText' })
export class ApiTextPipe implements PipeTransform {
constructor(private myApiService: MyApiService) {
}
transform(key: string): Observable {
return this.myApiService.getText(key);
}
}
我必须像这样使用它:
{{'some-key' | apiText | async}}
但实际上,我将始终希望结合使用apiText
和async
管道。我更喜欢这样写:
{{'some-key' | apiTextAsync}}
我能以某种方式做到这一点,并通过组合两个管道使事情变得更干燥吗?
更新:我已打开GitHub问题作为对此功能的解决方案的功能要求。
Jeroen..
5
一些评论者指出(正确地如此),这违反了SRP,并可能会损害可读性。但是,即使这会让我重新考虑我是否要这个,我仍然肯定想知道如何做到这一点,如果你想要它。我找到了两个解决方案(再次在评论者的帮助下)。
成分(不推荐)
创建自己的内部AsyncPipe
并使用它。这是应该工作的基本设置:
@Pipe({ name: 'apiText', pure: false })
export class ApiTextPipe implements PipeTransform, OnDestroy {
private asyncPipe: AsyncPipe;
constructor(private myApiService: MyApiService, private injector: Injector) {
this.asyncPipe = new AsyncPipe(injector.get(ChangeDetectorRef));
}
ngOnDestroy() {
this.asyncPipe.ngOnDestroy();
}
transform(key: string): string {
return this.asyncPipe.transform(this.myApiService.getText(key));
}
}
除了上述缺点(评论者注意到)之外,我还看到其他问题:
如果AsyncPipe发生了变化(例如,它开始实现)OnInit
,那么我们自己的管道也需要更改。您可能会错过这一点。我们管道的实现以这种方式耦合到AsyncPipe不好。
我似乎无法AsyncPipe
注射,因为它依赖于special ChangeDetectorRef
,所以我使用了这种建议的方法,直接从注射器中询问它。(可能有更好的方法来执行此操作,但是我现在不进一步探讨...)
继承(不推荐)
您也可以尝试extends AsyncPipe
在自己的管道中进行操作,但是该路线的代码更加笨拙,将您的管道与异步管道紧密耦合。当我尝试这种方法时,存在一些问题:
您再次需要ChangeDetectorRef
转接到super(...)
通话
您需要紧密结合到transform
方法的签名AsyncPipe
在transform
得到超级复杂,因为它不再只是需要一个字符串(参见前一点)
我不知道这是否正确使Angular调用超类的ngOnDestroy
方法
再加上我忘记的一切。我觉得代码很讨厌,甚至共享它似乎也不明智。
复制源(不推荐)
正如评论者之一建议的那样,的来源AsyncPipe
是开放的。因此,您可以采用它并以此构建自己的管道。
由于明显的原因,这不是明智的决定。
最重要的是,我现在对自己的问题的答案(尽管我很高兴地证明另一个答案是错误的!)是,这不容易实现,最好的解决方案是不解决任何问题:只需坚持使用二重奏模板。
1> Jeroen..:
一些评论者指出(正确地如此),这违反了SRP,并可能会损害可读性。但是,即使这会让我重新考虑我是否要这个,我仍然肯定想知道如何做到这一点,如果你想要它。我找到了两个解决方案(再次在评论者的帮助下)。
成分(不推荐)
创建自己的内部AsyncPipe
并使用它。这是应该工作的基本设置:
@Pipe({ name: 'apiText', pure: false })
export class ApiTextPipe implements PipeTransform, OnDestroy {
private asyncPipe: AsyncPipe;
constructor(private myApiService: MyApiService, private injector: Injector) {
this.asyncPipe = new AsyncPipe(injector.get(ChangeDetectorRef));
}
ngOnDestroy() {
this.asyncPipe.ngOnDestroy();
}
transform(key: string): string {
return this.asyncPipe.transform(this.myApiService.getText(key));
}
}
除了上述缺点(评论者注意到)之外,我还看到其他问题:
如果AsyncPipe发生了变化(例如,它开始实现)OnInit
,那么我们自己的管道也需要更改。您可能会错过这一点。我们管道的实现以这种方式耦合到AsyncPipe不好。
我似乎无法AsyncPipe
注射,因为它依赖于special ChangeDetectorRef
,所以我使用了这种建议的方法,直接从注射器中询问它。(可能有更好的方法来执行此操作,但是我现在不进一步探讨...)
继承(不推荐)
您也可以尝试extends AsyncPipe
在自己的管道中进行操作,但是该路线的代码更加笨拙,将您的管道与异步管道紧密耦合。当我尝试这种方法时,存在一些问题:
您再次需要ChangeDetectorRef
转接到super(...)
通话
您需要紧密结合到transform
方法的签名AsyncPipe
在transform
得到超级复杂,因为它不再只是需要一个字符串(参见前一点)
我不知道这是否正确使Angular调用超类的ngOnDestroy
方法
再加上我忘记的一切。我觉得代码很讨厌,甚至共享它似乎也不明智。
复制源(不推荐)
正如评论者之一建议的那样,的来源AsyncPipe
是开放的。因此,您可以采用它并以此构建自己的管道。
由于明显的原因,这不是明智的决定。
最重要的是,我现在对自己的问题的答案(尽管我很高兴地证明另一个答案是错误的!)是,这不容易实现,最好的解决方案是不解决任何问题:只需坚持使用二重奏模板。