angular 为使用函数作为管道添加支持

h4cxqtbf  于 6个月前  发布在  Angular
关注(0)|答案(7)|浏览(45)

与功能请求相关的@angular/*包?

core

描述

目前,为了创建一个自定义管道,需要编写大量的样板代码。您需要将 @Pipe 装饰器添加到您创建的整个类中,以便可以扩展 PipeTransform 并实现通常最终是一个小转换或逻辑片段的功能。
这让人想起了旧的 CanActivate(Children)CanDeactivate(Children) 类,它们已被弃用,以支持 Can(De)ActivateFn 。我建议对管道进行类似的更改,这将允许开发人员减少他们必须编写的样板代码数量,同时允许开发人员将小型或非常特定的管道保留在他们使用的类文件中,因为该函数可以在类上定义。

建议的解决方案

创建一个 PipeFn 类,该类定义了函数作为管道工作所需的输入/输出,并允许将函数用作管道而不是整个类。

考虑的其他替代方案

另一种选择是修改 @Pipe 装饰器,使其可以用于类或函数,或者为函数创建不同的装饰器以将其标记为管道。

whlutmcx

whlutmcx2#

当前,为了创建一个自定义管道,有大量的样板代码。你需要将@pipe装饰器添加到你创建的整个类中,这样你就可以扩展PipeTransform并实现通常最终是一个小转换或逻辑的部分。
tl;dr;我绝对同意这种观点,尽管我们需要更深入地了解管道在哪些地方真正有用,以及创建它们是值得的。然而,对于某些情况来说,创建管道只是纯粹的开销,人们应该使用函数或计算属性而不是。

管道的优点

虽然transform函数是每个管道的核心,但这只是一个函数,而管道的实际好处是:

  • 管道有一个构造函数,允许它们在给定表达式包含管道第一次被求值时注入依赖项并执行逻辑;这是非常独特且方便的...如果一个人需要创建时间依赖项/逻辑;
  • 纯管道会被缓存;
  • 管道为创建和重用共享逻辑提供了一些结构。

对于希望创建具有依赖关系的相当复杂管道的库作者来说,管道是非常出色的。

管道的替代方案

没有构造函数的管道

非纯管道

首先,如果给定的管道没有任何构造函数并且不是纯的 那么它没有成为管道的理由 -只需创建一个普通的TypeScript函数即可。

纯管道

纯管道没有构造函数的主要好处是它们的缓存能力。我非常同意在这个特定情况下,将函数作为管道会非常有用。
对于使用信号的应用来说,computed可能是一个好的替代方案。

有构造函数的管道

那些确实有构造函数的管道表明存在一些创建/初始化逻辑,从这个意义上说,为管道创建一个类是有用的。我们可以使用工厂函数代替,但这只是在没有明确好处的情况下引入了一种不同的做事方式。

将函数作为管道

根据上面的讨论,我们可以看到将函数注册为管道对于没有构造函数的纯管道来说将是最大的好处。因此,如果我们沿着这条路走下去,它将只涵盖一部分用例,并引入两种做事方式。
但是假设我们确实想要沿着这条路走下去,让我们看看可能的API设计

技术解决方案

装饰器

#24559中,建议在一个函数上使用装饰器,遗憾的是,这在TS /即将到来的TC39规范中是不支持的。

示例方法

这个问题建议使用指令的示例成员作为管道。这很有挑战性,因为没有地方可以指定管道的元数据(是否纯还是不纯)。这可以通过装饰器来完成,例如:

@Component({
    ...,
    template: `{{'hi' | upper}}`
})
class MyComponent {
   @Pipe({pure: true})
   upper(value: number): string {
        return value.toUpperCase();
   }
}

这里的缺点是这些管道与给定组件的示例绑定在一起,不再容易共享。

ar5n3qh5

ar5n3qh53#

鉴于我之前评论的背景,我不确定实施管道替代语法是否具有足够的好处。
我们真正想要的是管道的缓存功能,但我们现在已经有信号了。

aamkag61

aamkag614#

还有一个问题是管道目前是一个完全自定义的语法。如果我们朝着使Angular表达式仅仅是TypeScript的方向发展,显然管道并不适合这个故事。

f4t66c6m

f4t66c6m5#

计算机的一个缺点是它们需要存储在某个地方,即它们不能是临时的。这可能是@for循环中的一个限制,其中管道有助于执行临时变换,而模板(或更准确地说,嵌入式视图)则作为存储位置。
一个闲暇的想法是在模板中声明一些语法来声明计算,这样就可以在嵌入式视图的上下文中声明计算了。

flvlnr44

flvlnr446#

目前我们创建了一个memoize管道,它接受一个函数并运行它。所以语法是:someFn | memoize:arg1:arg2someFn必须是纯函数,不能访问this。它基本上满足了我们的需求。

我认为@JoostK说的是一个好主意,尽管我不确定如何实现它,以及它是否实际上是模板局部变量的一部分(另一个问题)。

pkmbmrz7

pkmbmrz77#

ngxtension callPipe / ApplyPipe 可以作为解决方法使用。
此外,utils-decoratorsTaiga UI 的 @tuiPure 装饰器也可以用于对函数进行缓存。

相关问题