web-dev-qa-db-fra.com

Utilisation de Pipes dans ngModel sur les éléments INPUT dans Angular

J'ai un champ HTML INPUT.

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

et je veux formater sa valeur et utiliser un canal existant:

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

et obtenez le message d'erreur:

Impossible d'avoir un tube dans une expression d'action

Comment puis-je utiliser des pipes dans ce contexte?

104
Lonely

Vous ne pouvez pas utiliser opérateurs d'expression de modèle (canal, enregistrer le navigateur) dans l'instruction de modèle:

(ngModelChange)="Template statements"

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

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

Comme les expressions de modèle, les instructions de modèle utilisent un langage qui ressemble à JavaScript. L'analyseur d'instruction de modèle diffère de l'analyseur d'expression de modèle et prend en charge spécifiquement les affectations de base (=) et les expressions de chaînage (avec; ou,).

Cependant, certaines syntaxes JavaScript ne sont pas autorisées :

  • nouveau
  • opérateurs d'incrémentation et de décrémentation, ++ et -
  • affectation d'opérateur, telle que + = et - =
  • les opérateurs de bits | et &
  • les opérateurs d'expression de modèle

Donc, vous devriez l'écrire comme suit:

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

Exemple de Plunker

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

La solution ici consiste à scinder la liaison en une liaison unidirectionnelle et une liaison d'événement, que la syntaxe [(ngModel)] englobe réellement. [] est une syntaxe de liaison unidirectionnelle et () est une syntaxe de liaison d'événement. Lorsqu'ils sont utilisés ensemble - [()] Angular reconnaît cela comme un raccourci et connecte une liaison bidirectionnelle sous la forme d'une liaison unidirectionnelle et d'une liaison d'événement à une valeur d'objet de composant.

La raison pour laquelle vous ne pouvez pas utiliser [()] avec un tuyau est que les tuyaux ne fonctionnent qu'avec des liaisons à sens unique. Par conséquent, vous devez séparer le tuyau pour n'opérer que sur la liaison unidirectionnelle et gérer l'événement séparément.

Voir Angular Syntaxe du modèle pour plus d'informations.

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

J'aimerais ajouter un point de plus à la réponse acceptée.

Si le type de votre contrôle d'entrée n'est pas textuel, le tube ne fonctionnera pas.

Gardez cela à l'esprit et économisez votre temps.

6
Tibin Thomas

J'ai essayé les solutions ci-dessus mais la valeur qui va au modèle était la valeur formatée qui revenait et me donnait des erreurs de currencyPipe. Donc je devais

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

Et sur la fonction de addToAmount -> changer sur flou parce que le ngModelChange me donnait des problèmes de curseur.

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

Et en supprimant les autres valeurs non numériques.

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

Ma solution est donnée ci-dessous ici searchDetail est un objet ..

<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">
0