Formattatori e parser ngModel


103

Ho pubblicato la stessa domanda in forma diversa, ma nessuno ha risposto. Non ottengo un'immagine chiara di ciò che fanno i formattatori e i parser in js angolare.

Per definizione, sia i formattatori che i parser mi sembrano simili. Forse mi sbaglio, dato che sono nuovo a questo angularjs.

Definizione di formattatori

Matrice di funzioni da eseguire, come una pipeline, ogni volta che il valore del modello cambia. Ciascuna funzione viene chiamata, a sua volta, passando il valore a quella successiva. Utilizzato per formattare / convertire i valori per la visualizzazione nel controllo e nella convalida.

Definizione di parser

Matrice di funzioni da eseguire, come una pipeline, ogni volta che il controllo legge il valore dal DOM. Ciascuna funzione viene chiamata, a sua volta, passando il valore a quella successiva. Utilizzato per disinfettare / convertire il valore e la convalida. Per la convalida, i parser devono aggiornare lo stato di validità utilizzando $ setValidity () e restituire undefined per i valori non validi.

Per favore aiutami a capire entrambe le caratteristiche con un semplice esempio. Sarà apprezzata una semplice illustrazione di entrambi.


2
I formattatori modificano il valore visualizzato di un modello, come la visualizzazione (123) 123-1234di un numero di telefono. I parser leggono i dati ogni volta che cambiano e in genere vengono utilizzati per impostare lo stato $ valid dell'input. I documenti hanno esempi di entrambi.
km6zla

Risposte:


155

Questo argomento è stato trattato molto bene in una domanda correlata: come eseguire il filtraggio a due vie in AngularJS?

Riassumere:

  • I formattatori modificano il modo in cui i valori del modello appariranno nella vista.
  • I parser modificano il modo in cui i valori della vista verranno salvati nel modello.

Ecco un semplice esempio, basato su un esempio nella documentazione dell'api NgModelController :

  //format text going to user (model to view)
  ngModel.$formatters.push(function(value) {
    return value.toUpperCase();
  });

  //format text from the user (view to model)
  ngModel.$parsers.push(function(value) {
    return value.toLowerCase();
  });

Puoi vederlo in azione: http://plnkr.co/UQ5q5FxyBzIeEjRYYVGX?plnkr=legacy

<input type="button" value="set to 'misko'" ng-click="data.name='misko'"/>
<input type="button" value="set to 'MISKO'" ng-click="data.name='MISKO'"/>
<input changecase ng-model="data.name" />

Quando digiti un nome in (view to model), vedrai che il modello è sempre minuscolo. Tuttavia, quando si fa clic su un pulsante e si modifica programmaticamente il nome (modello da visualizzare), il campo di input è sempre maiuscolo.


2
c'è un modo per impostare questa modifica mentre l'utente digita? Dici "programmaticamente", ma sto cercando di formattare $ viewValue quando l'utente entra nell'input, ad esempio per la formattazione del numero di carta di credito
iamyojimbo

3
@SavvasNicholas Se non sbaglio, useresti ngModel.$setViewValue(transformedInput);per impostarlo e ngModel.$render();renderlo dalla funzione $ parsers.
Jacob Ensor

Nel mio caso, cosa $formattersfare, viene immediatamente ripristinato da $validators. ; (
Mikhail Batcer

1
Cordiali saluti, il plunkr a cui si fa riferimento non esiste più
Chris Brown il

1
Noto che il formattatore funziona solo se si preme il pulsante, non se si digita il nome nel campo
nuander

6

Un altro utilizzo per formattatori e parser è quando si desidera memorizzare le date in ora UTC e visualizzarle in ora locale sugli input, ho creato la direttiva datepicker di seguito e il filtro utcToLocal per questo.

(function () {
    'use strict';

    angular
        .module('app')
        .directive('datepicker', Directive);

    function Directive($filter) {
        return {
            require: 'ngModel',
            link: function (scope, element, attr, ngModel) {
                element.addClass('datepicker');
                element.pickadate({ format: 'dd/mm/yyyy', editable: true });

                // convert utc date to local for display
                ngModel.$formatters.push(function (utcDate) {
                    if (!utcDate)
                        return;

                    return $filter('utcToLocal')(utcDate, 'dd/MM/yyyy');
                });

                // convert local date to utc for storage
                ngModel.$parsers.push(function (localDate) {
                    if (!localDate)
                        return;

                    return moment(localDate, 'DD/MM/YYYY').utc().toISOString();
                });
            }
        };
    }
})();

Utilizza questo filtro utcToLocal che garantisce che la data di input sia nel formato corretto prima della conversione nell'ora locale.

(function () {
    'use strict';

    angular
        .module('app')
        .filter('utcToLocal', Filter);

    function Filter($filter) {
        return function (utcDateString, format) {
            if (!utcDateString) {
                return;
            }

            // append 'Z' to the date string to indicate UTC time if the timezone isn't already specified
            if (utcDateString.indexOf('Z') === -1 && utcDateString.indexOf('+') === -1) {
                utcDateString += 'Z';
            }

            return $filter('date')(utcDateString, format);
        };
    }
})();

moment.js viene utilizzato per convertire le date locali in utc.

pickadate.js è il plug-in datepicker utilizzato

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.