Réinitialiser le formulaire à l’état vierge (AngularJS 1.0.x)

Une fonction pour réinitialiser les champs de formulaire à l’état vierge (réinitialiser l’état sale) se trouve sur la feuille de route pour AngularJS 1.1.x. Malheureusement, une telle fonction est absente de la version stable actuelle.

Quelle est la meilleure façon de réinitialiser tous les champs de formulaire à leur état initial initial pour AngularJS 1.0.x.

Je voudrais savoir si cela est réparable avec une directive ou une autre solution simple. Je préfère une solution sans avoir à toucher aux sources AngularJS d’origine. Pour clarifier et démontrer le problème, un lien vers JSFiddle. http://jsfiddle.net/juurlink/FWGxG/7/

La fonctionnalité souhaitée figure 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 Demande de tirage – https://github.com/angular/angular.js/pull/1127

Mise à jour avec une solution de contournement possible

Bonne solution de contournement?

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

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

Et dans mon contrôleur sur resetForm() :

  • Enregistrez le code HTML d’origine intact
  • Recomstackr le HTML original enregistré
  • Supprimer le formulaire actuel du DOM
  • Insérez le nouveau modèle compilé dans le DOM

Le JavaScript:

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

Solution sans solution de contournement

Je suis venu avec une solution qui utilise AngularJS sans aucune solution de contournement. L’astuce consiste à utiliser la capacité d’AngularJS pour avoir plus d’une directive avec le même nom.

Comme d’autres l’ont mentionné, il y a en fait une demande d’extraction ( https://github.com/angular/angular.js/pull/1127 ) qui a été ajoutée à la twig AngularJS 1.1.x qui permet de réinitialiser les formulaires. La validation de cette requête pull modifie les directives ngModel et form / ngForm (j’aurais aimé append un lien mais Stackoverflow ne veut pas que j’ajoute plus de deux liens).

Nous pouvons maintenant définir nos propres directives ngModel et form / ngForm et les étendre avec les fonctionnalités fournies dans la requête pull.

J’ai encapsulé ces directives dans un module AngularJS nommé resettableForm. Tout ce que vous avez à faire est d’inclure ce module dans votre projet et votre version 1.0.x d’AngularJS se comporte comme s’il s’agissait d’une version 1.1.x angular à cet égard.

“Une fois que vous mettez à jour à 1.1.x vous n’avez même pas besoin de mettre à jour votre code, supprimez simplement le module et vous avez terminé!”

Ce module passe également tous les tests ajoutés à la twig 1.1.x pour la fonctionnalité de réinitialisation de formulaire.

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

Etape 1: Inclure le module réinitialisable 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 = { ressortingct: 'E', require: ['form'], comstack: 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), {ressortingct: '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: Fournissez une méthode sur votre contrôleur qui réinitialise le modèle

Veuillez noter 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

 
(Required, but no other validators)

Field is required

Pristine: {{form.$pristine}}

Je pense que cela vaut la peine de mentionner que dans les versions ultérieures d’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 à l’état vierge.

FormController. $ SetPristine

EDIT … Je retire ma vieille réponse, car ce n’était pas suffisant.

En fait, j’ai juste rencontré ce problème moi-même et voici ma solution: j’ai créé une méthode d’extension pour angular. Je l’ai fait en suivant un peu ce que $ scope.form. $ SetValidity () faisait (en sens inverse) …

Voici une démo de plnkr en action

Voici la méthode d’aide que j’ai faite. C’est un hack, mais ça marche:

 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]; } }; 

J’espère que cela est utile à quelqu’un.

Vos champs de formulaire doivent être liés à une variable dans votre $ scope. Vous pouvez réinitialiser le formulaire en réinitialisant les variables. Ce devrait probablement être un object unique 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 bien tant que votre HTML ressemble à:

 

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

Ici, j’ai trouvé une solution pour mettre le de son état d’origine.

 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; } }; 

Écrivez simplement angular.extends (src, dst) , de sorte que votre object d’origine ne fasse que prolonger l’object vide, qui apparaîtra comme vide et reposera tous par défaut.

Utiliser une directive externe et beaucoup de jquery

 app.controller('a', function($scope) { $scope.caca = function() { $scope.$emit('resetForm'); } }); app.directive('form', function() { return { ressortingct: 'E', link: function(scope, iElem) { scope.$on('resetForm', function() { iElem.find('[ng-model]').andSelf().add('[ng-form]').each(function(i, elem) { var target = $(elem).addClass('ng-pristine').removeClass('ng-dirty'); var control = target.controller('ngModel') || target.controller('form'); control.$pristine = true; control.$dirty = false; }); }); } }; }); 

http://jsfiddle.net/pPbzz/2/

Le moyen le plus simple: passez simplement le formulaire dans la fonction contrôleur. Sous le formulaire “myForm” est référencé par ceci , ce qui équivaut à $ scope.

 

Le controlle:

 function MyController(MyService) { var self = this; self.myFormValues = { name: 'Chris' }; self.doSomething = function (form) { var aform = form; MyService.saveSomething(self.myFromValues) .then(function (result) { ... aform.$setPristine(); }).catch(function (e) { ... aform.$setDirty(); }) } }