angular 当他们读取的信号发生变化时,标记纯管道为脏,

kcwpcxri  于 5个月前  发布在  Angular
关注(0)|答案(4)|浏览(49)

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

core

描述

目前,如果纯管道的 transform 方法读取信号,当信号发生变化时,管道不会重新执行。
请参阅 https://stackblitz.com/edit/stackblitz-starters-eadv1h?file=src%2Fmain.ts 作为示例。
这对我来说反直觉,原因如下:

  1. 管道用于模板中,因此模板间接地是信号的“客户端”,所以当信号发生变化时,更新模板似乎合乎逻辑
  2. OnPush 的规则已经改变以利用信号:即使 OnPush 组件没有输入发生变化,但当它读取的信号发生变化时,组件也会被标记为检查。从概念上讲,纯管道与 OnPush 组件非常相似:只有在其参数发生变化时才会重新执行。由于现在 OnPush 也会在模板读取的信号发生变化时标记组件进行检查,因此我认为对于读取信号的纯管道也应该这样做
    通过这样的更改可能会改变现有管道的行为,但当前行为可以通过在 untracked() 内部读取信号来实现。另一方面,那些因读取信号而被标记为不纯的管道可以变得纯粹。

建议的解决方案

即使其参数没有发生变化,也要重新执行管道,以防它读取的信号发生变化。

考虑过的其他替代方案

?

zengzsys

zengzsys1#

虽然我们可以进行这种更改,但关于纯管道在信号方面的实用性有一个更广泛的问题。我们的思考是,大多数纯管道的使用将被 computed 取代。这对你的案例是否有效?如果无效,你能否分享更多关于你的特定情况的信息?

sd2nnvve

sd2nnvve2#

@pkozlowski-opensource
一个计算属性肯定会起作用。
我认为管道是在模板中重用数据转换逻辑的一种相对简单的方法,而不是在组件内部暴露计算信号。
让我们假设日期管道使用了一个全局配置的信号来持有时区或区域设置,或者首选的模式。我更喜欢需要导入DatePipe并能够使用{{ someObject().someDate | date }},而不是需要将

formattedDate = computed(() => formatDate(someObject().someDate));

添加到组件中。
如果Angular从头开始围绕信号设计,我的猜测是管道将不存在。但既然它们存在,我认为它们应该以最直观的方式工作,并与框架的其他部分保持一致,即信号的变化会导致模板刷新。
老实说,我没有一个真正的特定用例。这个问题出现在Angular Discord的一个问题中,其中有人询问更新信号是否会导致管道重新执行。

8hhllhi2

8hhllhi23#

嗯,我想你真正想做的是类似这样的东西:signal() | mappingFunction,你只需要提供一个源信号和一个纯函数。computed部分已经为你完成。

06odsfpq

06odsfpq4#

当我们可以进行这个改变时,有一个关于纯管道在信号中实用性的更广泛的问题。我们的思考是,大多数纯管道的使用将被 computed 取代。这对你的情况有效吗?如果无效,你能分享更多关于你特定场景的信息吗?

我认为这是一个错误的假设。我使用了很多在 ngFor 中有额外参数的管道。例如:

<ng-container *ngFor="let item of list()">
  <div>{{ otherSignal() | somePipe : item }}</div>
</ng-container>

我不确定如何创建具有不同参数的计算或计算工厂之类的东西?我认为管道仍然是一种非常有用和有帮助的方式,可以将某些逻辑隔离开来,而不是反复插入到多个组件的计算属性中。
我还在处理一些奇怪的行为,当我们使用扩展运算符将新对象放入带有信号的容器中时,一切都正常。但是,当我们想要优化时,我们向信号添加了一个等于函数,这导致了在使用管道的信号上出现了奇怪的行为,因为管道只触发了一次。

相关问题