Usando Pipes dentro de ngModel em elementos INPUT em Angular

Eu tenho um campo HTML INPUT.

 

e quero formatar seu valor e usar um pipe existente:

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

e receba a mensagem de erro:

Não é possível ter um canal em uma expressão de ação

Como posso usar pipes neste contexto?

Você não pode usar os operadores de expressão de modelo (pipe, save navigator) na declaração do template:

 (ngModelChange)="Template statements" 

(ngModelChange) = “item.value | useMyPipeToFormatThatValue = $ event”

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

Como as expressões de modelo, as declarações de modelo usam uma linguagem parecida com JavaScript. O analisador de instrução de modelo difere do analisador de expressões de modelo e suporta especificamente as expressões de atribuição básica (=) e de encadeamento (com; ou,).

No entanto, certas syntaxs JavaScript não são permitidas :

  • Novo
  • operadores de incremento e decremento, ++ e –
  • atribuição de operador, como + = e – =
  • os operadores bit a bit | e &
  • os operadores de expressão de modelo

Então você deve escrever da seguinte forma:

  

Exemplo de Plunker

  

A solução aqui é dividir a binding em uma binding unidirecional e em uma binding de evento – que a syntax [(ngModel)] realmente abrange. [] é uma syntax de binding unidirecional e () é a syntax de binding de evento. Quando usados ​​juntos – [()] Angular reconhece isso como uma forma abreviada e liga uma binding bidirecional na forma de uma binding unidirecional e uma binding de evento para um valor de object componente.

O motivo pelo qual você não pode usar [()] com um pipe é que os pipes funcionam somente com ligações unidirecionais. Portanto, você deve dividir o pipe para operar somente na binding unidirecional e manipular o evento separadamente.

Veja Sintaxe de modelo angular para mais informações.

Eu tentei as soluções acima ainda o valor que vai para o modelo foram o valor formatado, em seguida, retornando e me dando erros de currencyPipe. Então eu tive que

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

E sobre a function de addToAmount -> alterar no desfoque causar o ngModelChange estava me dando problemas de cursor.

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

E removendo os outros valores não numéricos.

 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(); } 

Minha solução é dada abaixo aqui searchDetail é um object ..

   
  

Eu gostaria de acrescentar mais um ponto à resposta aceita.

Se o tipo de controle de input não for texto, o canal não funcionará.

Tenha isso em mente e economize seu tempo.