【问题标题】:Why does ng-messages for form validation not work when using $rollbackViewValue为什么使用 $rollbackViewValue 时表单验证的 ng-messages 不起作用
【发布时间】:2014-12-29 15:19:48
【问题描述】:

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

我真的很喜欢 angular1.3 中的这个新功能,它使用 ng-model-options 来重置表单,因为我没有找到任何能像 $rollbackViewValue() 一样工作的东西

这是代码和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 格。重置表单上所有原始值的最佳方法是什么?
  • 我能想到的唯一方法就是我的回答方式。事实上,我在angular documentation example 看到他们也这样做。如果您认为它对您有用,我可以取消删除我的答案。
  • 是的,我相信您的回答会成功。您可以用 plunker 再次发布您的解决方案吗?
  • 当然,添加了堆栈溢出演示的答案。

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


【解决方案1】:

您需要使表单保持原始状态并恢复触摸状态。您可以通过调用 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>

【讨论】:

  • 是的,但这并不能解决 ng-messages 显示错误的问题
  • @jmccommas 可能我理解错了。如果您运行演示删除说 fname 并单击提交,您将看到正确的错误,然后单击重置,它将隐藏它。不是这个问题吗?
  • 问题与我们在表单标签上的 data-ng-model-options="{updateOn: 'submit'}" 有关。如果您将其删除,则会出现错误消息 wot=rk
  • 啊,我没看到。我不确定你是否可以使用 ng-modal 选项提交,因为提交事件发生在表单上,​​并且这个 ngmodel 分配将提交事件应用于输入,这与输入元素上的事件不同,例如说: - 更改或模糊事件。
  • 我们将表单 attr 更改为 data-ng-model-options="{updateOn: 'blur'}" 它可以工作,但是重置按钮不再将数据重置为原始状态
猜你喜欢
  • 2016-08-03
  • 1970-01-01
  • 1970-01-01
  • 2012-02-02
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多