63 votes

Réinitialiser le formulaire en état vierge (AngularJS 1.0.x)

Une fonction pour réinitialiser les champs de formulaire à l'état initial (reset sale état) est sur la feuille de route pour AngularJS 1.1.x. Malheureusement, une telle fonction est manquante à partir de la version stable actuelle.

Quel est le meilleur moyen pour réinitialiser tous les champs de formulaire à leur premier état impeccable pour AngularJS 1.0.x.?

Je voudrais savoir si c'est réparable avec une directive ou d'une autre solution de contournement simple. Je préfère une solution sans avoir à toucher à l'original AngularJS sources. Afin de clarifier et d'illustrer le problème, un lien vers JSFiddle. http://jsfiddle.net/juurlink/FWGxG/7/

Fonction souhaitée est sur la feuille de route - http://blog.angularjs.org/2012/07/angularjs-10-12-roadmap.html
Demande de fonctionnalité - https://github.com/angular/angular.js/issues/856
Solution proposée Pull request - https://github.com/angular/angular.js/pull/1127

Mis à jour avec la solution de contournement possible

Bon assez de solution de contournement?

Je viens de comprendre que je peux recompiler la partie HTML et de le remettre dans les DOM. Il fonctionne et c'est bien pour une solution temporaire, mais aussi comme @blesh mentionné dans les commentaires:

Les contrôleurs doivent être utilisés pour la logique métier uniquement, pas pour les DOM!

<div id="myform">
  <form class="form-horizontal" name="form">
  </form>
</div>

Et dans mon Contrôleur resetForm():

  • Enregistrer l'original intact HTML
  • Recompiler le sauvé HTML d'origine
  • Supprimer la forme actuelle du DOM
  • Insérez le nouveau modèle compilé dans le DOM

Le JavaScript:

var pristineFormTemplate = $('#myform').html();
$scope.resetForm = function () {
    $('#myform').empty().append($compile(pristineFormTemplate)($scope));
}

85voto

Matthias Dailey Points 967

Je pense que cela vaut la peine de mentionner que dans les versions ultérieures de Angular (par exemple 1.1.5), vous pouvez appeler $ setPristine sur le formulaire.

 $scope.formName.$setPristine(true)
 

Cela définira également tous les contrôles de formulaire sur un état vierge.

FormController. $ SetPristine

32voto

jupiter Points 2236

Solution sans solution de contournement

Je suis venu avec une solution qui utilise AngularJS, sans aucune solution de contournement. L'astuce ici est d'utiliser AngularJS possibilité d'avoir plus d'une directive portant le même nom.

Comme d'autres l'ont mentionné, il est en fait un pull request (https://github.com/angular/angular.js/pull/1127) qui l'a fait dans le AngularJS 1.1.x branche qui permet à des formes d'être réinitialisé. La validation de cette demande de pull modifie la ngModel et la forme/ngForm directives (j'aurais bien aimé ajouter un lien, mais Stackoverflow ne veut pas de moi d'ajouter plus de deux liens).

Nous pouvons maintenant définir notre propre ngModel et la forme/ngForm directives et d'étendre les fonctionnalités fournies dans la demande d'extraction.

J'ai enveloppé ces directives dans un AngularJS module nommé resettableForm. Tout ce que vous avez à faire est d'inclure ce module dans votre projet et votre AngularJS la version 1.0.x se comporte comme si elle était Angulaire 1.1.x version à cet égard.

"Une fois la mise à jour 1.1.x vous n'avez même pas à mettre à jour votre code, il suffit de retirer le module et vous avez terminé!"

Ce module passe tous les tests ajouté à la 1.1.x direction générale pour la forme fonctionnalité de réinitialisation.

Vous pouvez voir le module de travail dans un exemple dans un jsFiddle (http://jsfiddle.net/jupiter/7jwZR/1/) j'ai créé.

Étape 1: Inclure la resettableform module dans votre projet

(function(angular) {

// Copied from AngluarJS
function indexOf(array, obj) {
  if (array.indexOf) return array.indexOf(obj);

  for ( var i = 0; i < array.length; i++) {
    if (obj === array[i]) return i;
  }
  return -1;
}

// Copied from AngularJS
function arrayRemove(array, value) {
  var index = indexOf(array, value);
  if (index >=0)
    array.splice(index, 1);
  return value;
}

// Copied from AngularJS
var PRISTINE_CLASS = 'ng-pristine';
var DIRTY_CLASS = 'ng-dirty';

var formDirectiveFactory = function(isNgForm) {
    return function() {
        var formDirective = {
            restrict: 'E',
            require: ['form'],
            compile: function() {
                return {
                    pre: function(scope, element, attrs, ctrls) {
                        var form = ctrls[0];
                        var $addControl = form.$addControl;
                        var $removeControl = form.$removeControl;
                        var controls = [];
                        form.$addControl = function(control) {
                            controls.push(control);
                            $addControl.apply(this, arguments);
                        }
                        form.$removeControl = function(control) {
                            arrayRemove(controls, control);
                            $removeControl.apply(this, arguments);
                        }
                        form.$setPristine = function() {
                            element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
                            form.$dirty = false;
                            form.$pristine = true;
                            angular.forEach(controls, function(control) {
                                control.$setPristine();
                            });
                        }
                    },
                };
            },
        };
        return isNgForm ? angular.extend(angular.copy(formDirective), {restrict: 'EAC'}) : formDirective;
    };
}
var ngFormDirective = formDirectiveFactory(true);
var formDirective = formDirectiveFactory();
angular.module('resettableForm', []).
    directive('ngForm', ngFormDirective).
    directive('form', formDirective).
    directive('ngModel', function() {
        return {
            require: ['ngModel'],
            link: function(scope, element, attrs, ctrls) {
                var control = ctrls[0];
                control.$setPristine = function() {
                    this.$dirty = false;
                    this.$pristine = true;
                    element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
                }
            },
        };
    });
})(angular);

Étape 2: Fournir une méthode sur votre contrôleur qui réinitialise le modèle

S'il vous plaît être conscient que vous devez réinitialiser le modèle lorsque vous réinitialisez le formulaire. Dans votre contrôleur, vous pouvez écrire:

var myApp = angular.module('myApp', ['resettableForm']);

function MyCtrl($scope) {
    $scope.reset = function() {
        $scope.form.$setPristine();
        $scope.model = '';
    };
}

Étape 3: Inclure cette méthode dans votre modèle HTML

<div ng-app="myApp">
<div ng-controller="MyCtrl">
<form name="form">
    <input name="requiredField" ng-model="model.requiredField" required/> (Required, but no other validators)
    <p ng-show="form.requiredField.$errror.required">Field is required</p>
    <button ng-click="reset()">Reset form</button>
</form>
<p>Pristine: {{form.$pristine}}</p>
</div>
</dvi>

7voto

Ben Lesh Points 39290

EDIT... je vais enlever mon ancienne réponse, car il n'était pas adéquate.

En fait je viens de tombé sur cette question de moi-même et voilà ma solution: j'ai fait une méthode d'extension angulaire. Je n'ai donc par la suite un peu de ce qu' $champ d'application.le formulaire.$setValidity() était en train de faire (en sens inverse)...

Voici un plnkr démo de en action

Voici la méthode d'assistance que j'ai fait. C'est un hack, mais il fonctionne:

angular.resetForm = function (scope, formName, defaults) {
    $('form[name=' + formName + '], form[name=' + formName + '] .ng-dirty').removeClass('ng-dirty').addClass('ng-pristine');
    var form = scope[formName];
    form.$dirty = false;
    form.$pristine = true;
    for(var field in form) {
      if(form[field].$pristine === false) {
        form[field].$pristine = true;
      }
      if(form[field].$dirty === true) {
        form[field].$dirty = false;
      }
    }
    for(var d in defaults) {
      scope[d] = defaults[d];
    }
};

Espérons que cela est utile à quelqu'un.

4voto

grendian Points 1144

Les champs de votre formulaire doivent être liés à une variable de votre portée $. Vous pouvez réinitialiser le formulaire en réinitialisant les variables. Ce devrait probablement être un seul objet comme $ scope.form.

Disons que vous avez un formulaire simple pour un utilisateur.

 app.controller('Ctrl', function Ctrl($scope){
  var defaultForm = {
    first_name : "",
    last_name : "",
    address: "",
    email: ""
  };
  $scope.resetForm = function(){
    $scope.form = defaultForm;
  };
});
 

Cela fonctionnera très bien tant que votre code HTML ressemble à:

 <form>
  <input ng-model="form.first_name"/>
  <input ng-model="form.last_name"/>
  <input ng-model="form.address"/>
  <input ng-model="form.email"/>
  <button ng-click="resetForm()">Reset Form</button>
</form>
 

Peut-être que je ne comprends pas le problème ici, alors si cela ne répond pas à votre question, pouvez-vous expliquer pourquoi exactement?

2voto

Laxmidhar Sahoo Points 21

Ici, j'ai trouvé une solution pour mettre le de à son état initial.

 var def = {
    name: '',
    password: '',
    email: '',
    mobile: ''
};

$scope.submited = false;

$scope.regd = function (user) {
    if ($scope.user.$valid) {
        $http.post('saveUser', user).success(function (d) {
            angular.extend($scope.user, def);
            $scope.user.$setPristine(true);
            $scope.user.submited = false;
        }).error(function (e) {});
    } else {
        $scope.user.submited = true;
    }
};
 

Il suffit d'écrire angular.extends (src, dst) , de sorte que votre objet d'origine étend simplement l'objet vide, qui apparaîtra comme vide et tous les autres sont par défaut.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X