【问题标题】:Call pipe on change with observable使用可观察的更改调用管道
【发布时间】:2026-02-12 06:15:01
【问题描述】:

我有一个用于转换温度值的自定义管道。我想在启动组件(完成)和 lang 值更改(不工作)时调用此管道。你能帮帮我吗?

我的烟斗:

@Pipe({
  name: 'temperatureConverter'
})
export class TemperatureConverterPipe implements PipeTransform {
value: number;

constructor(private _translateService: TranslateService, private language: LanguageProvider) {
    this.language.getLanguage().subscribe((value) => {
        this.transform(this.value, value.lang);
    })

}

transform(value: number, unit : string = this.language.selectedLanguage) {
    this.value = value;

    if(value && !isNaN(value)){

        if(unit === 'fr'){
            let tempareature = (value - 32) / 1.8 ;
            return tempareature.toFixed(2) + " °C";
        }
        if(unit === 'en'){
            let tempareature = (value * 32) + 1.8 ;
            return tempareature.toFixed(2) + " F";
        }
    }
    return;
}

}

【问题讨论】:

  • 管道从组件中调用,它们返回一个简单的 value 进行渲染。你问的没有意义,单凭管道是无法处理的。

标签: angular pipe observable


【解决方案1】:

更新: 解决方案是将“纯”标志设置为假。这样就解决了问题。

@Pipe({
  name: 'TemperatureConverter',
  pure: false
})

--- 上一个答案---

我也有同样的问题。我发现将语言作为参数是可行的。不是我所希望的,但这可能对某人有用。这将在更改语言时更新字段。

在组件的构造函数中使用管道订阅随着语言的变化。另一种方式(你的方式)需要你重新加载组件:

lang: string;
constructor(private languageService: LanguageService) {
    this.languageService.language$.subscribe(l => this.lang = l);

  }

在组件中像这样使用管道:

<span>3 | TemperatureConverter : lang</span

【讨论】:

    【解决方案2】:

    如果您要订阅 到管道内的可观察对象,则必须在管道被销毁时取消订阅。您使用 takeUntil() 使用 ngOnDestroy 回调自动取消订阅。

     export class TemperatureConverterPipe implements PipeTransform, OnDestroy {
         private _destroyed: Subject<void> = new Subject();
         public ngOnDestroy {
            this._destroyed.next();
            this._destroyed.complete();
         }
     }
    

    当你改变管道的 internal 状态时,你必须通知 Angular view 已经改变。您可以使用 ChangeDetectorRef 来做到这一点。

     private lang: any;
    
     constructor(private _translateService: TranslateService, 
                 private language: LanguageProvider,
                 private ref: ChangeDetectorRef) {
         this.language.getLanguage()
              .pipe(takeUntil(this._destroyed))
              .subscribe((value) => {
                     this.lang = value;
                     ref.markForCheck();
               });
    }
    

    您现在可以在转换函数中使用来自getLanguage() 服务的值。

    transform(value: number, unit?: string) {
       unit = unit || this.lang;
       ....
    }
    

    当服务发出语言更改时,管道将触发视图上的更改检测,您应该会看到视图已更新。

    【讨论】:

      【解决方案3】:

      感谢您发布博客。 我遇到了与管道相关的同样问题。 我尝试在参数更改时调用管道。 但这不是正确的同步方式。 因此,我使用函数来显示值何时更改,而不是那样。 而不是 {{ 标签 |标签格式}}, 我使用了 {{ labelFormat(labels)}}。

      我在 ts 文件中定义了 labelFormat 函数。 谢谢。

      【讨论】:

      • 欢迎使用 Stack Overflow?如果您想赞扬某人,您可以点赞他的帖子或发表评论,但不能回复
      【解决方案4】:

      您首先需要将管道注册到模块声明中。之后,您可以通过

      在您的html页面中调用它
      {{ myTempDegree | temperatureConverter : 'fr' }}
      

      【讨论】:

      • 这没有回答 OP 的问题,当LanguageProvider 发出一个新的selectedLanguage 时,呈现的值将更新。
      • 他不能将 BehavıorSubject 用于 myTempDegree 吗?
      • 他们可以,但是它需要经过async 之前点击temperatureConverter,它仍然不会合并两个流。
      • 让我们等待 OP 的评论。我相信这篇文章已经超出了范围。顺便说一句,谢谢您的评论