如何在Angular中有条件地动态添加管道?

How to add pipes conditionally and dynamically in Angular?

我有多个管道,想根据输入元素的条件添加一个或多个管道。

必须检查输入元素 (this) 是否具有特定样式 (this.styles),并且根据该样式,必须向输入元素添加管道。

因此,如果样式是 ReverseString,则管道 reverseStr 必须添加到输入元素。

我创建了管道,当我添加它时管道可以正常工作(参见 reverseStr):

<input type="text"
    #formItem
    [name]="id"
    [id]="id"
    class="form-control"
    [ngModel]="value | reverseStr"
    (blur)="change.emit(formItem.value)"/>

但是如何在 Angular 中有条件地添加管道?

我知道可以在 HTML 中添加如下内容:

[ngModel]="styles.includes('ReverseString') ? (value | SomePipe) : (value | pipe2)"

但这不是我认为最优雅的方式,如果我有多个输入组件,我需要每次都更改它

我创建了一个像这样的函数:

addPipe() {
const mapping: any = {
    ReverseString: 'reverseStr',
    LowerCase: 'lowerCase',
    UpperCase: 'upperCase',
};

this.styles.forEach((style : any) => {
    const pipes = mapping[style];
    if (pipes) {
        // How can I add the pipes now dynamically? 
    }
});

}

但我不知道如何将管道动态添加到输入字段。

如何在Angular中有条件地动态添加管道?

你可以有一个通用的管道组件,你可以在你的模板中有参数化的管道,

所以你的模板中有这样的东西,

<input type="text"
    #formItem
    [name]="id"
    [id]="id"
    class="form-control"
    [ngModel]="value | customPipe:desiredStyle"
    (blur)="change.emit(formItem.value)"/>

其中 'customPipe' 是您的管道,'desiredStyle' 是您的参数(以“:”分隔),您可以处理管道内的逻辑

请参考此stackblitz example以便更好地理解!

为了将动态 Pipesinput 一起使用,您只需将 ngModel 绑定到 settersgetters 的组件。方法如下:

1. 通过 Setters 和 Getters 绑定文本输入 ngModel

2. 检查输入的特定条件,如果计算结果为真则使用管道

 // component.ts  

 private _value;

  get value() {
    if(this.nameInput) {
      const inputClasses = this.nameInput.nativeElement.getAttribute('class');

      if(inputClasses.indexOf('reverse') !== -1) {
        return (new ReverseStrPipe).transform(this._value);
      } 
    }
    return this._value;
  }

  set value(val) {
    this._value = val;
  }

// component.html
<input type="text"
 #nameInput
[(ngModel)]="value"/>

这是 stackblitz 示例