使用$ rollbackViewValue时,为什么表单验证的ng-messages不起作用

时间:2014-12-29 15:19:49

标签: angularjs angularjs-ng-model angularjs-validation

我有一个表单,使用ng-messages表单验证错误消息。我还使用带有$ rollbackViewValue的新ng-model-options来回滚对表单的所有更改。问题是如果我在表单上使用rollbackViewValue,则ng-mesages将无效。

我真的很喜欢angular1.3中的这个新功能,使用ng-model-options来重置表单,因为我没有发现任何与$ rollbackViewValue()

一样的功能

Heres是代码plunker

<!DOCTYPE html>
    <html data-ng-app="App">
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"/>
    </head>
    <body>
    <div class="container" data-ng-controller="formCrtl as vm">
        <div class="col-lg-5">
        <form name="form" novalidate="novalidate" role="form"
              data-ng-submit="vm.submit()"
              data-ng-model-options="{updateOn: 'submit'}" >
            <!---->
            <div class="form-group"  data-ng-class="{ 'has-error': form.fname.$invalid && form.fname.$touched }">
                <label for="fname">First Name</label>
                <input type="text" required class="form-control" name="fname" id="fname" placeholder="Enter text" data-ng-model="vm.names.fname">
                <div data-ng-if="form.fname.$touched" data-ng-messages="form.fname.$error">
                    <span class="help-block" data-ng-message="required">required field</span>
                </div>
            </div>
            <div class="form-group" data-ng-class="{ 'has-error': form.lname.$invalid && form.lname.$touched }">
                <label for="lname">Last Name</label>
                <input type="text" required class="form-control" name="lname" id="lname" placeholder="Enter text" data-ng-model="vm.names.lname">
                <div data-ng-if="form.lname.$touched" data-ng-messages="form.lname.$error">
                    <span class="help-block" data-ng-message="required">required field</span>
                </div>
            </div>
            <div class="col-sm-offset-2 col-sm-10 btn-group">
                <button type="submit" class="btn btn-primary" data-ng-disabled="form.$invalid">Submit</button>
                <button type="button" class="btn btn-default" data-ng-click="form.$rollbackViewValue()">reset</button>
                <!---->
            </div>
        </form>
        </div>
    </div>


    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.8/angular.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.8/angular-messages.js"></script>
    <script src="scripts.js"></script>
    </body>
    </html>

控制器

var App = angular.module("App", ['App', 'ngMessages']);
App.controller('formCrtl',function ($scope, $rootScope) {

    var vm = this;
    vm.names = {
        fname: "Albert",
        lname: "Capone"
    }
});

1 个答案:

答案 0 :(得分:4)

您需要使表单保持原始状态并恢复触摸状态。您可以通过在formController上调用特殊函数$setPristine()$setUntouched()来完成此操作。但看起来rollBackViewValue与ngSubmit一起使用,但它只是在某些操作中恢复(如esc键,另一个按钮)。但是如果表单字段具有约束错误,则会显示更新的viewvalue以使输入的值无效。您可以通过重置为默认字段值来尝试这种方式。

在您看来: -

 <button type="button" class="btn btn-default" 
     data-ng-click="vm.reset(form)">reset</button>

在您的控制器中: -

 var vm = this;
  var defModel = {
    fname: "Albert",
    lname: "Capone"
  };

  vm.names = angular.copy(defModel);

  vm.reset = function(form) {
    form.$rollbackViewValue();
    form.$setPristine(); //Set pristine state
    form.$setUntouched(); //Set state from touched to untouched
    vm.names = angular.copy(defModel); //reset model
  }

var App = angular.module("App", ['App', 'ngMessages']);
App.controller('formCrtl', function($scope, $rootScope) {

  var vm = this;
  var defModel = {
    fname: "Albert",
    lname: "Capone"
  };

  vm.names = angular.copy(defModel);


  vm.reset = function(form) {
    form.$rollbackViewValue(); //Probably can be removed
    form.$setPristine();
    form.$setUntouched();
   
    vm.names = angular.copy(defModel);
     
  }
});
<div data-ng-app="App">

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />

  <div class="container" data-ng-controller="formCrtl as vm">
    <div class="col-lg-5">
      <form name="form" novalidate="novalidate" role="form" data-ng-submit="vm.submit(form)" data-ng-model-options="{updateOn: 'submit'}">
        <!---->
        <div class="form-group" data-ng-class="{ 'has-error': form.fname.$invalid && form.fname.$touched }">
          <label for="fname">First Name</label>
          <input type="text" required class="form-control" name="fname" id="fname" placeholder="Enter text" data-ng-model="vm.names.fname">
          <div data-ng-if="form.fname.$touched" data-ng-messages="form.fname.$error">
            <span class="help-block" data-ng-message="required">required field</span>
          </div>
        </div>
        <div class="form-group" data-ng-class="{ 'has-error': form.lname.$invalid && form.lname.$touched }">
          <label for="lname">Last Name</label>
          <input type="text" required class="form-control" name="lname" id="lname" placeholder="Enter text" data-ng-model="vm.names.lname">
          <div data-ng-if="form.lname.$touched" data-ng-messages="form.lname.$error">
            <span class="help-block" data-ng-message="required">required field</span>
          </div>
        </div>
        <div class="col-sm-offset-2 col-sm-10 btn-group">
          <button type="submit" class="btn btn-primary" data-ng-disabled="form.$invalid">Submit</button>
          <button type="button" class="btn btn-default" data-ng-click="vm.reset(form)">reset</button>
          <!---->
        </div>
      </form>
    </div>
  </div>


  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.8/angular.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.8/angular-messages.js"></script>
</div>