没有解决方法的解决方案
我想出了一个解决方案,它使用 AngularJS 而没有任何解决方法。这里的技巧是使用 AngularJS 的能力来拥有多个具有相同名称的指令。
正如其他人提到的那样,实际上有一个拉取请求(https://github.com/angular/angular.js/pull/1127),它进入了允许重置表单的 AngularJS 1.1.x 分支。对此拉取请求的提交会更改 ngModel 和 form/ngForm 指令(我本来想添加一个链接,但 Stackoverflow 不希望我添加两个以上的链接)。
我们现在可以定义自己的 ngModel 和 form/ngForm 指令,并使用拉取请求中提供的功能扩展它们。
我已经将这些指令包装在一个名为 resettableForm 的 AngularJS 模块中。您所要做的就是将此模块包含到您的项目中,并且您的 AngularJS 版本 1.0.x 在这方面表现得就好像它是 Angular 1.1.x 版本一样。
''一旦你更新到 1.1.x,你甚至不必更新你的代码,只需删除模块,你就完成了!''
该模块还通过了为表单重置功能添加到 1.1.x 分支的所有测试。
您可以在我创建的 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>