Angular.js imposta a livello di codice un campo modulo su sporco


105

Sto aggiornando a livello di codice alcuni dei campi del mio modulo con un valore e vorrei impostare lo stato del campo su $dirty. Fare qualcosa come:

$scope.myForm.username.$dirty = true; non sembra funzionare.

Esiste un metodo $setPristineche posso utilizzare per ripristinare lo stato del campo ma non esiste un $setDirtymetodo?

Allora come si fa a farlo?

Ho visto questo post https://groups.google.com/forum/#!topic/angular/NQKGAFlsln4 ma non riesco a trovare il $setDirtymetodo. Sto usando la versione Angular 1.1.5.


potrebbe essere necessario impostare un valore (predefinito)?
Cherniv

3
Il metodo $ setDirty è documentato qui: docs.angularjs.org/api/ng.directive:form.FormController
David Lin

2
Sembra essere a livello di forma. Ho bisogno di un $setDirtylivello di campo.
super9

andando su un arto qui, ma una possibile, ma piuttosto complicata, soluzione a questo sarebbe scoprire quale listener di eventi utilizza angular per legarsi a quel tipo di campo e attivare quell'ascoltatore manualmente immediatamente dopo l'aggiornamento. </uglyHack>
bguiz

Stavo pensando di cambiare la classe a livello di codice ma non cambierà lo stato del campo del modulo nel modo corretto avrei pensato ...
super9

Risposte:


51

A partire da AngularJS 1.3.4 puoi usare $setDirty()sui campi ( sorgente ). Ad esempio, per ogni campo con errore e contrassegnato come obbligatorio puoi eseguire le seguenti operazioni:

angular.forEach($scope.form.$error.required, function(field) {
    field.$setDirty();
});

87

Nel tuo caso, $scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue);fa il trucco: sporca sia il modulo che il campo e aggiunge le classi CSS appropriate.

Giusto per essere onesto, ho trovato questa soluzione nel nuovo post nell'argomento dal link dalla tua domanda. Ha funzionato perfettamente per me, quindi lo metto qui come risposta autonoma per renderlo più facile da trovare.

MODIFICARE:

La soluzione sopra funziona meglio per la versione angolare fino alla 1.3.3. A partire dalla 1.3.4 dovresti usare il metodo API appena esposto $setDirty()da ngModel.NgModelController.


Questo è sembrato cambiare per me tra Angular 1.3.0-beta5 e 1.3.0, dove 1.3.0 mantiene il campo $ intatto finché $ viewValue non è cambiato. Ho dovuto fare $scope.myForm.myField.$pristine = false; $scope.myForm.myField.$setViewValue(...). Sembra che la risposta di seguito affermando che è field.$setDirty()stata aggiunta in Angular 1.3.4 sarà la soluzione migliore
Johann

4
Grazie per la tua nota mi hai salvato la giornata "fino alla 1.3.3. A partire dalla 1.3.4 dovresti usare il metodo API appena esposto"
Ahmed Mahmoud

user rmag, e che dire di angular 2?
user5260143

17

dovrai impostare manualmente $dirtysu truee $pristinesu falseper il campo. Se vuoi che le classi appaiano nel tuo input, dovrai aggiungere ng-dirtye rimuovere manualmente le ng-pristineclassi dall'elemento. È possibile utilizzare $setDirty()a livello di modulo per fare tutto ciò sul modulo stesso, ma non gli input del modulo, gli input del modulo attualmente non hanno $setDirty()come hai menzionato.

Questa risposta potrebbe cambiare in futuro poiché dovrebbero aggiungersi $setDirty()agli input, sembra logico.


3
$ setPristine () è a livello di campo di input ma ancora non $ setDirty in 1.2.26 :-(
Sebastian

10

Se hai accesso a NgModelController (puoi accedervi solo da una direttiva), puoi chiamare

ngModel.$setViewValue("your new view value");
// or to keep the view value the same and just change it to dirty
ngModel.$setViewValue(ngModel.$viewValue);

Grazie! Esattamente quello che stavo cercando.
dreyln

10

Ho creato un jsFiddle solo per te che risolve questo problema. imposta semplicemente $ dirty su true, ma con $timeout 0così viene eseguito dopo che DOM è stato caricato.

Lo trovi qui: JsFiddle

$timeout(function () {
  $scope.form.uName.$dirty = true;
}, 0);

6

Questo è ciò che ha funzionato per me

$scope.form_name.field_name.$setDirty()


5

Una funzione di supporto per svolgere il lavoro:

function setDirtyForm(form) {
    angular.forEach(form.$error, function(type) {
        angular.forEach(type, function(field) {
            field.$setDirty();
        });
    });
    return form;
}

Ehi, sfortunatamente, ho accidentalmente svalutato questo. Come lo ripristino. Quindi mi dice che non posso farlo senza che la risposta venga modificata ..
smk

Funziona bene; upvoting come controllo per 'form. $ error' assicura che non stiamo 'dirtificando' i campi che l'utente non ha toccato, ma che sono validi.
Sam T

Grazie! Soluzione facile e semplice. Potrebbe non essere il più veloce ma non fa nulla di pesante quindi non importa davvero. Buon lavoro!
jwanglof

4

Angolare 2

Per chiunque cerchi di fare lo stesso in Angular 2 è molto simile a parte ottenere una presa del modulo

<form role="form" [ngFormModel]="myFormModel" (ngSubmit)="onSubmit()" #myForm="ngForm">
<div class="form-group">
    <label for="name">Name</label>
    <input autofocus type="text" ngControl="usename" #name="ngForm" class="form-control" id="name" placeholder="Name">
    <div [hidden]="name.valid || name.pristine" class="alert alert-danger">
        Name is required
    </div>
</div>
</form>
<button type="submit" class="btn btn-primary" (click)="myForm.ngSubmit.emit()">Add</button>

import { Component, } from '@angular/core';
import { FormBuilder, Validators } from '@angular/common';

@Component({
    selector: 'my-example-form',
    templateUrl: 'app/my-example-form.component.html',
    directives: []
})
export class MyFormComponent {
    myFormModel: any;

    constructor(private _formBuilder: FormBuilder) {
        this.myFormModel = this._formBuilder.group({
            'username': ['', Validators.required],
            'password': ['', Validators.required]
        });
    }

    onSubmit() {
        this.myFormModel.markAsDirty();
        for (let control in this.myFormModel.controls) {
            this.myFormModel.controls[control].markAsDirty();
        };

        if (this.myFormModel.dirty && this.myFormModel.valid) {
            // My submit logic
        }
    }
}

3

Piccola nota aggiuntiva alla risposta di @ rmag. Se hai campi vuoti ma obbligatori che vuoi sporcare usa questo:

$scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue !== undefined 
    ? $scope.myForm.username.$viewValue : '');

Questa è la risposta che finalmente mi ha aiutato!
Kirk Liemohn

-1

Non sono sicuro del motivo per cui stai cercando di contrassegnare i campi come sporchi, ma mi sono trovato in una situazione simile perché volevo che gli errori di convalida venissero visualizzati quando qualcuno ha tentato di inviare un modulo non valido. Ho finito per usare jQuery per rimuovere i .ng-pristinetag di classe e aggiungere .ng-dirtyi tag di classe ai campi appropriati. Per esempio:

$scope.submit = function() {
    // `formName` is the value of the `name` attribute on your `form` tag
    if (this.formName.$invalid)
    {
        $('.ng-invalid:not("form")').each(function() {
            $(this).removeClass('ng-pristine').addClass('ng-dirty');
        });
        // the form element itself is index zero, so the first input is typically at index 1
        $('.ng-invalid')[1].focus();
    }
}

5
Dato che stiamo già utilizzando AngularJS, una soluzione jQuery sembra eccessiva. Molte persone preferiscono non usare jQuery con AngularJS, ad esempio.
StevenClontz
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.