代码之家  ›  专栏  ›  技术社区  ›  Jeroen

创建自身异步的自定义管道

  •  5
  • Jeroen  · 技术社区  · 6 年前

    我创建了一个自定义管道,用于从API中检索文本内容,如下所示:

    @Pipe({ name: 'apiText' })
    export class ApiTextPipe implements PipeTransform {
      constructor(private myApiService: MyApiService) {
      }
    
      transform(key: string): Observable<string> {
        return this.myApiService.getText(key);
      }
    }
    

    我必须这样使用它:

    <strong>{{'some-key' | apiText | async}}</strong>
    

    但实际上我会的 总是 想要结合 apiText async 管。我想写这个:

    <strong>{{'some-key' | apiTextAsync}}</strong>
    

    我能这样做吗?把两根管子组合起来,让东西干一点?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Community Marino Di Clemente    6 年前

    一些评论指出(正确地说)这违反了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是不好的。

    • 我好像不能 异步管道 注射是因为它依赖于特殊的 ChangeDetectorRef ,所以我用 this suggested approach 直接从注入器中询问。(可能有更好的方法,但目前我还没有进一步挖掘…)

    继承 (不推荐)

    你也可以尝试 extends AsyncPipe 在您自己的管道中,但是该路径包含更笨拙的代码,这些代码将您的管道紧紧地连接到异步管道上。我尝试这种方法时遇到了一些问题:

    • 你又需要一个 变化检测器参考 传递给 super(...) 呼叫
    • 你需要紧紧地结合在 transform 方法来自 异步管道
    • 这个 转型 变得非常复杂,因为它不再只需要一个字符串(见上一点)
    • 我不知道这是否能恰当地称为超类 ngOnDestroy 方法

    再加上我忘了什么。我觉得代码太恶心了,甚至分享它似乎都不明智。

    复制源 (不推荐)

    正如一位评论者所说, the source for AsyncPipe 打开。所以你可以用它来做你自己的管道。

    显然,这不是明智的决定。


    总之,我现在对自己的问题的答案(尽管我很高兴被证明是另一个错误的答案!)它不容易实现,最好的解决方案是不解决任何问题:只需在模板中使用两个管道。