如何重置表单,包括删除所有验证错误?

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)

  • 注意其他人,这种方法可以有效地总结如下:"`form.$ setPristine()`不会清除错误.你必须将所有表单控件显式设置回`undefined`." (4认同)

小智 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)


Ari*_*iel 5

您可以添加验证标志,并根据HTML的值ng-ifng-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


Mic*_*ael 5

似乎没有一种简单的方法来重置角度中的$ 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)