【问题标题】:Angular : Redraw Pipe based on observable valueAngular:基于可观察值重绘管道
【发布时间】:2021-12-16 15:42:57
【问题描述】:

我有一堆正在处理本地化的自定义管道:

例如,这里有一个简单的管道,它将根据语言显示全名/姓氏或姓氏/全名:

@Pipe({ name: 'fullname' })
export class FullnamePipe implements PipeTransform, OnDestroy {
  private language = Language.EN_US;
  private subscriptions = new SubSink();

  constructor(private translateService: TranslateService) {
    this.language = LanguageUtils.toAppLanguage(this.translateService.currentLang);
    this.subscriptions.add(
      this.translateService.onLangChange.subscribe(({ lang }) => {
        this.language = LanguageUtils.toAppLanguage(lang);
      })
    );
  }

  transform(value: string, language?: Language): string {
    const [firstname, lastname] = value.split('|');
    const firstNameFirst = LanguageUtils.isFirstNameFirst(language || this.language);
    return firstNameFirst ? `${firstname} ${lastname}` : `${lastname} ${firstname}`;
  }

  ngOnDestroy() {
    this.subscriptions.unsubscribe();
  }
}

现在这是一堆功能完全相同的管道之一,只是变换方法发生了变化。

我希望这些管道能够根据this.language 更改自己重绘(因此更改其显示值)。

现在,我知道至少有两种解决方案:

  • 使用pure:false 它会起作用,因为更改语言会触发检测。但这样做的缺点是管道每次检测触发时都会运行,而不仅仅是语言。所以这太矫枉过正了。

  • 添加一个参数(如上),但这意味着每个使用管道的组件实际上都需要将一个 observable 传递给具有语言值的管道。这使得每个组件都比应有的“更智能”。

有没有一种解决方案可以让我根据需要手动重绘管道?

【问题讨论】:

  • AFAIK 需要更改参数值,否则必须将管道设置为 pure: false 才能调用 transform

标签: angular angular-pipe


【解决方案1】:

将管道设置为{ pure: false } 绝对不是性能问题,除非组件中有数千个管道。

第二个命题不仅使组件更智能,而且还涉及async 管道,它也是不纯的,并且比第一个解决方案具有稍高的性能影响 - 除非你这样做,否则这又不是一个问题您的模板中有一些非常错误的地方。

如果您需要在 ChangeDetectionStrategy.OnPush 上下文中的语言更改时重绘,我假设您已经这样做了,因为它比简单的不纯管道具有更高的性能影响,请不要忘记在语言订阅中调用 ChangeDetectorRef.markForCheck .

【讨论】:

  • 在某些情况下我确实有一百个(他们根据本地语言格式化日期)。我想我还是会去的。谢谢
  • 我会说一百是可以的。您的转换操作非常简单,如果您将转换结果缓存为最后一个值,则不会有太大区别。
猜你喜欢
  • 1970-01-01
  • 2018-08-12
  • 2020-09-05
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-27
  • 2019-06-05
相关资源
最近更新 更多