Использование труб в ngModel для элементов INPUT в угловом

У меня есть поле ввода HTML.

<input 
    [(ngModel)]="item.value" 
    name="inputField" 
    type="text" 
/>

и я хочу отформатировать его значение и использовать существующий канал:

.... 
[(ngModel)]="item.value | useMyPipeToFormatThatValue" 
....

и получите сообщение об ошибке:

Не может быть трубы в выражении действия

Как я могу использовать трубы в этом контексте?

Ответ 1

Вы не можете использовать операторы выражения шаблона (pipe, save navigator) в инструкции шаблона:

(ngModelChange)="Template statements"

(ngModelChange) = "item.value | useMyPipeToFormatThatValue = $ event"

https://angular.io/guide/template-syntax#template-statements

Как и выражения шаблонов, операторы шаблонов используют язык, похожий на JavaScript. Парсер анализатора шаблонов отличается от синтаксического анализатора шаблонов и, в частности, поддерживает как базовое присваивание (=), так и цепочки выражений (с; или,).

Однако определенный синтаксис JavaScript не допускается:

  • новый
  • операторы приращения и уменьшения, ++ и -
  • оператор, например, + = и - =
  • поразрядные операторы | а также &
  • операторы выражения шаблона

Поэтому вы должны написать его следующим образом:

<input [ngModel]="item.value | useMyPipeToFormatThatValue" 
      (ngModelChange)="item.value=$event" name="inputField" type="text" />

Пример плунжера

Ответ 2

<input [ngModel]="item.value | useMyPipeToFormatThatValue" 
      (ngModelChange)="item.value=$event" name="inputField" type="text" />

Решение здесь состоит в том, чтобы разделить привязку на одностороннюю привязку и привязку события, которая действительно охватывает синтаксис [(ngModel)]. [] - синтаксис одностороннего связывания, а () - синтаксис привязки событий. При использовании вместе - [()] Angular распознает это как стенографию и связывает двустороннюю привязку в форме односторонней привязки и привязки события к значению объекта компонента.

Причина, по которой вы не можете использовать [()] с каналом, заключается в том, что каналы работают только с односторонними связями. Поэтому вы должны разделить трубу только на одностороннюю привязку и обрабатывать событие отдельно.

Подробнее см. Angular Синтаксис шаблонов.

Ответ 3

Я пробовал решения выше, но значение, которое идет к модели, было форматированным значением, а затем возвращалось и давало мне ошибки CurrencyPipe. Так что я должен был

  [ngModel]="transfer.amount | currency:'USD':true"
                                   (blur)="addToAmount($event.target.value)"
                                   (keypress)="validateOnlyNumbers($event)"

И при использовании функции addToAmount → change on blur причина ngModelChange давала мне проблемы с курсором.

removeCurrencyPipeFormat(formatedNumber){
    return formatedNumber.replace(/[$,]/g,"")
  }

И удаление других не числовых значений.

validateOnlyNumbers(evt) {
  var theEvent = evt || window.event;
  var key = theEvent.keyCode || theEvent.which;
  key = String.fromCharCode( key );
  var regex = /[0-9]|\./;
  if( !regex.test(key) ) {
    theEvent.returnValue = false;
    if(theEvent.preventDefault) theEvent.preventDefault();
  }

Ответ 4

<input [ngModel]="item.value | currency" (ngModelChange)="item.value=$event"
name="name" type="text" />

Я хотел бы добавить еще один момент к принятому ответу.

Если тип вашего элемента управления вводом не текстовый, канал не будет работать.

Имейте это в виду и сэкономьте свое время.

Ответ 5

Мое решение приведено ниже здесь searchDetail - это объект.

<p-calendar  [ngModel]="searchDetail.queryDate | date:'MM/dd/yyyy'"  (ngModelChange)="searchDetail.queryDate=$event" [showIcon]="true" required name="queryDate" placeholder="Enter the Query Date"></p-calendar>

<input id="float-input" type="text" size="30" pInputText [ngModel]="searchDetail.systems | json"  (ngModelChange)="searchDetail.systems=$event" required='true' name="systems"
            placeholder="Enter the Systems">