bat*_*anz 24 html angularjs ng-messages
我有一个Angular表格.使用该ng-pattern属性验证字段.我也有一个重置按钮.我正在使用Ui.Utils Event Binder来处理这样的reset事件:
<form name="searchForm" id="searchForm" ui-event="{reset: 'reset(searchForm)'}" ng-submit="search()">
<div>
<label>
Area Code
<input type="tel" name="areaCode" ng-model="areaCode" ng-pattern="/^([0-9]{3})?$/">
</label>
<div ng-messages="searchForm.areaCode.$error">
<div class="error" ng-message="pattern">The area code must be three digits</div>
</div>
</div>
<div>
<label>
Phone Number
<input type="tel" name="phoneNumber" ng-model="phoneNumber" ng-pattern="/^([0-9]{7})?$/">
</label>
<div ng-messages="searchForm.phoneNumber.$error">
<div class="error" ng-message="pattern">The phone number must be seven digits</div>
</div>
</div>
<br>
<div>
<button type="reset">Reset</button>
<button type="submit" ng-disabled="searchForm.$invalid">Search</button>
</div>
</form>
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,当表单重置时,它会调用表单上的reset方法$scope.这是整个控制器的样子:
angular.module('app').controller('mainController', function($scope) {
$scope.resetCount = 0;
$scope.reset = function(form) {
form.$setPristine();
form.$setUntouched();
$scope.resetCount++;
};
$scope.search = function() {
alert('Searching');
};
});
Run Code Online (Sandbox Code Playgroud)
我正在打电话,form.$setPristine()并form.$setUntouched按照Stack Overflow上另一个问题的建议.我添加计数器的唯一原因是证明代码被调用(它是).
问题是即使重置表单后,验证消息也不会消失.你可以在Plunker上看到完整的代码.这是一个屏幕截图,显示错误不会消失:

bat*_*anz 22
我从@Brett的评论开始并以此为基础.我实际上有多个表单,每个表单都有很多字段(不仅仅是显示的两个字段).所以我想要一个通用的解决方案
我注意到Angular form对象具有每个控件(input,select,textarea等)的属性以及一些其他Angular属性.但是,每个Angular属性都以美元符号($)开头.所以我最终做了这个(包括为其他程序员的好处发表评论):
$scope.reset = function(form) {
// Each control (input, select, textarea, etc) gets added as a property of the form.
// The form has other built-in properties as well. However it's easy to filter those out,
// because the Angular team has chosen to prefix each one with a dollar sign.
// So, we just avoid those properties that begin with a dollar sign.
let controlNames = Object.keys(form).filter(key => key.indexOf('$') !== 0);
// Set each control back to undefined. This is the only way to clear validation messages.
// Calling `form.$setPristine()` won't do it (even though you wish it would).
for (let name of controlNames) {
let control = form[name];
control.$setViewValue(undefined);
}
form.$setPristine();
form.$setUntouched();
};
Run Code Online (Sandbox Code Playgroud)
小智 7
$scope.search = {areaCode: xxxx, phoneNumber: yyyy}
Run Code Online (Sandbox Code Playgroud)
在上面的一个地方构建表单中的所有模型,因此您可以像这样清除它:
$scope.search = angular.copy({});
Run Code Online (Sandbox Code Playgroud)
之后你可以调用它来重置验证:
$scope.search_form.$setPristine();
$scope.search_form.$setUntouched();
$scope.search_form.$rollbackViewValue();
Run Code Online (Sandbox Code Playgroud)
您可以添加验证标志,并根据HTML的值ng-if或ng-show在HTML中显示或隐藏错误.表单有一个$ valid标志,您可以将其发送给您的控制器.
ng-if将删除或重新创建DOM的元素,同时ng-show将添加它但不显示它(取决于标志值).
编辑:正如迈克尔所指出的,如果表单被禁用,我指向的方式将无效,因为表单永远不会被提交.相应地更新了代码.
HTML
<form name="searchForm" id="searchForm" ui-event="{reset: 'reset(searchForm)'}" ng-submit="search()">
<div>
<label>
Area Code
<input type="tel" name="areaCode" ng-model="areaCode" ng-pattern="/^([0-9]{3})?$/">
</label>
<div ng-messages="searchForm.areaCode.$error">
<div class="error" ng-message="pattern" ng-if="searchForm.areaCode.$dirty">The area code must be three digits</div>
</div>
</div>
<div>
<label>
Phone Number
<input type="tel" name="phoneNumber" ng-model="phoneNumber" ng-pattern="/^([0-9]{7})?$/">
</label>
<div ng-messages="searchForm.phoneNumber.$error">
<div class="error" ng-message="pattern" ng-if="searchForm.phoneNumber.$dirty">The phone number must be seven digits</div>
</div>
</div>
<br>
<div>
<button type="reset">Reset</button>
<button type="submit" ng-disabled="searchForm.$invalid">Search</button>
</div>
</form>
Run Code Online (Sandbox Code Playgroud)
JS
$scope.search = function() {
alert('Searching');
};
$scope.reset = function(form) {
form.$setPristine();
form.$setUntouched();
$scope.resetCount++;
};
Run Code Online (Sandbox Code Playgroud)
Codepen与工作解决方案:http://codepen.io/anon/pen/zGPZoB
似乎没有一种简单的方法来重置角度中的$ errors.最好的方法可能是重新加载当前页面以使用新表单开始.或者,您必须使用此脚本手动删除所有$ error:
form.$setPristine(true);
form.$setUntouched(true);
// iterate over all from properties
angular.forEach(form, function(ctrl, name) {
// ignore angular fields and functions
if (name.indexOf('$') != 0) {
// iterate over all $errors for each field
angular.forEach(ctrl.$error, function(value, name) {
// reset validity
ctrl.$setValidity(name, null);
});
}
});
$scope.resetCount++;
Run Code Online (Sandbox Code Playgroud)