web-dev-qa-db-fra.com

Angular 4 - comment rendre 2 décimales pour le type = 'input'

Cette question concerne la restriction/validation de l'entrée lorsque l'utilisateur entre des données dans une entrée de type numéro.

Le problème que j'ai, c'est que lors du premier chargement du modèle, tous les nombres qui sont des entiers ou 1dp sont rendus avec seulement 1dp. Par exemple, 40 ou 40.0 indiquent 40.0 (et non 40.00).

J'ai ajouté ce code pour qu'après qu'un utilisateur ait saisi une nouvelle valeur, il affiche avec 2dp:

dans le fichier modèle:

(change)="setTwoNumberDecimal($event)"

dans le fichier de composant:

  setTwoNumberDecimal($event) {
    $event.target.value = parseFloat($event.target.value).toFixed(2);
  }

Cela fonctionne pour afficher 2dp après l'utilisateur modifie la valeur.

J'ai essayé d'écrire une directive qui devrait formater en 2dp lors du chargement initial des données, mais bien que la directive soit déclenchée, elle ne change pas la valeur en 2dp.

import { Directive, ElementRef, Input, Renderer2 } from '@angular/core';

@Directive ({
  selector: '[fbDecimalFormat]'
})

export class DecimalFormatDirective {

  constructor(private el: ElementRef,
              private renderer: Renderer2) {
    //renderer.setAttribute(el, 'value', parseFloat(el.nativeElement.value).toFixed(2));
    this.el.nativeElement.value = parseFloat(this.el.nativeElement.value).toFixed(2);
  }

}

Pour votre information, la ligne de rendu commentée ne fonctionnait pas (erreur: setAttribute non reconnue) - il s'agissait d'une tentative d'être indépendante de la plate-forme.

La question est donc: Comment puis-je obtenir l’entrée qui rend sa valeur initiale avec 2dps?

2
rmcsharry

Modèles de formulaire

La solution à ce problème consistait à utiliser la variable DecimalPipe intégrée (numéro étrangement appelé) et à ne pas utiliser de liaison bidirectionnelle pour la valeur du modèle - c'est-à-dire. de [(ngModel)] à [ngModel] et (ngModelChange)

    <input type="number" step="0.01" 
            (change)="setTwoNumberDecimal($event)"
            (ngModelChange)="item.value=$event"
            [ngModelOptions]="{updateOn: 'blur'}"
            [ngModel]="setting.decimal_value | number:'1.2-2'">

Voir cette question pour plus d’informations sur le fractionnement de la liaison [()].

Notez également que la mise à jour ne se déclenche que lorsque l'utilisateur quitte le contrôle (flou), sinon chaque fois qu'il tapera quelque chose, il mettra à jour, ce qui sera une frustrante UX (grâce au commentaire de @ Mihail).

Formes réactives

_ {En réponse à la question posée dans les commentaires: "Cela pourrait-il également être utilisé avec des formes réactives?"

La réponse est:

Non, utiliser des tuyaux avec des formes réactives est plus compliqué. Vous pouvez utiliser le tuyau uniquement pour afficher la valeur, comme

 <p>{{form.get('name').value | myPipe}}</p> 

mais je pense que la bonne façon est d'utiliser value accessor. Plus d'infos ici .

6
rmcsharry

Number.toFixed (x) Formate un nombre quelconque pour "x" nombre de décimales de fin. Le nombre est arrondi et les "0" sont utilisés après le signe décimal si nécessaire pour créer la longueur décimale souhaitée. Dans le modèle, nous pouvons formater la valeur et valider les valeurs

value1 = 0
value2 = 0.0

<p>
  {{value1.toFixed(2)}} - shows 0.00
  {{value2.toFixed(2)}} - shows 0.00
</p>
0
MukundK