将表单重置为原始状态(AngularJS 1.0.x)

将表单字段重置为原始状态(重置脏状态)的function位于AngularJS 1.1.x的路线图中。 不幸的是,目前的稳定版本中没有这样的function。

将AngularJS 1.0.x的所有表单字段重置为初始状态的最好方法是什么?

我想知道这是否可以解决与指令或其他简单的解决方法。 我更喜欢一个解决scheme,而不必接触原始的AngularJS源代码。 澄清和演示问题,JSFiddle的链接。 http://jsfiddle.net/juurlink/FWGxG/7/

期望的function在路线图上 – http://blog.angularjs.org/2012/07/angularjs-10-12-roadmap.html
function请求 – https://github.com/angular/angular.js/issues/856
build议的解决scheme请求 – https://github.com/angular/angular.js/pull/1127

更新可能的解决方法

足够好的解决方法?

我只是想通了,我可以重新编译的HTML部分,并把它放回到DOM。 它的工作原理,暂时的解决scheme是好的,但也可以在评论中提到@blesh:

控制器只能用于业务逻辑,而不能用于DOM!

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

并在我的控制器resetForm()

  • 保存原始的未触及的HTML
  • 重新编译保存的原始HTML
  • 从DOM中删除当前表单
  • 将新编译的模板插入到DOM中

JavaScript:

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

没有解决方法的解决scheme

我想出了一个没有任何解决方法的使用AngularJS的解决scheme。 这里的诀窍是使用AngularJS能够拥有多个具有相同名称的指令。

正如其他人提到的那样,实际上有一个pull请求( https://github.com/angular/angular.js/pull/1127 ),它使它进入AngularJS 1.1.x分支,允许重置表单。 提交这个拉请求会改变ngModel和form / ngForm指令(我希望添加一个链接,但Stackoverflow不希望我添加两个以上的链接)。

我们现在可以定义我们自己的ngModel和form / ngForm指令,并使用pull请求中提供的function来扩展它们。

我已经将这些指令包装在名为resettableForm的AngularJS模块中。 所有你需要做的就是把这个模块包含到你的项目中,你的AngularJS版本1.0.x就像在这方面是一个Angular 1.1.x版本一样。

一旦你升级到1.1.x,你甚至不需要更新你的代码,只需要移除模块,就完成了!“

此模块还将所有添加到1.1.x分支的testing传递给窗体重置function。

你可以在我创build的jsFiddle( http://jsfiddle.net/jupiter/7jwZR/1/ )中的例子中看到该模块工作。

步骤1:在您的项目中包含resettableform模块

 (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); 

步骤2:在您的控制器上提供重置模型的方法

请注意,当您重置表单时,您必须重置模型。 在你的控制器中,你可以写:

 var myApp = angular.module('myApp', ['resettableForm']); function MyCtrl($scope) { $scope.reset = function() { $scope.form.$setPristine(); $scope.model = ''; }; } 

第3步:将此方法包含在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> 

我认为值得一提的是,在更高版本的Angular(例如1.1.5)中,您可以在窗体上调用$setPristine

 $scope.formName.$setPristine(true) 

这将把所有的表单控件设置为原始状态。

的FormController。$ setPristine

编辑…我删除了我的旧答案,因为它不够。

我其实自己也碰到过这个问题,这里是我的解决scheme:我做了一个angular度的扩展方法。 我这样做是通过以下几点$ scope.form。$ setValidity()在做(反向)…

这是一个在行动中的plnkr演示

这是我做的帮手方法。 这是一个黑客,但它的工作原理:

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

希望这对某人有帮助。

您的表单字段应该链接到您的$范围内的variables。 您可以通过重置variables来重置表单。 它应该是一个单一的对象,如$ scope.form。

比方说,你有一个简单的forms为用户。

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

只要您的html如下所示,这将工作得很好:

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

也许我不是在这里理解这个问题,所以如果这不能解决你的问题,你能解释一下为什么?

在这里,我find了一个解决scheme,把它从原始的状态。

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

只需写angular.extends(src,dst) ,这样你的原始对象只是扩展了空白对象,而这个空白对象将会显示为空白,而且所有的都是默认的。

使用外部指令和大量的jQuery

 app.controller('a', function($scope) { $scope.caca = function() { $scope.$emit('resetForm'); } }); app.directive('form', function() { return { restrict: '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/

简单的方法是:将表单传递给控制器​​函数。 下面的表单“myForm”被引用,这相当于$ scope。

 <div ng-controller="MyController as mc"> <ng-form name="myform"> <input ng-model="mc.myFormValues.name" type="text" required> <button ng-click="mc.doSometing(this.myform)" type="submit" ng-disabled="myform.$invalid||myform.$pristine">Do It!</button> </ng-form> </div> 

控制器:

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