【问题标题】:How to manually trigger AngularJS validation from a button outside of the form tags?如何从表单标签外的按钮手动触发 AngularJS 验证?
【发布时间】:2017-02-24 18:13:14
【问题描述】:

鉴于此代码:

<div ng-controller="MyCtrl">
    <form ng-submit="onSubmitted()">

    Header inputs:
        <input type="name" ng-model="sample" required/>
        <input type="name" ng-model="sampleX" required/>

        <input type="submit" value="This submit triggers validation. But I wanted to put this button at the end of the page"/>
    </form>

    <hr/>

    Some other form here. Think line items

    <hr />
    <a class="btn" ng-click="/* what could should be put here, so this can trigger the firt form's validation, then submit? */">Wanted this submit button to trigger the validation+submit on the form in which this button doesn't belong</a>


</div>


var app = angular.module('myApp', []);

function MyCtrl($scope) {

    $scope.onSubmitted = function() {
        alert('submitted!');
    };
}

我希望最后一个按钮在第一个表单上触发验证(然后在事情有效时提交)。到目前为止,只有表单内的按钮可以触发该表单的验证和提交。表单外的按钮是否有任何可能的方式来做到这一点?

现场测试:http://jsfiddle.net/dzjV4/1/

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    您可以创建指令,然后将其附加到&lt;a class="btn"...。检查这个jsfiddle

    http://jsfiddle.net/dzjV4/2/

    请注意,我添加到&lt;input type='submit' id='clickMe'... 并将其链接到底部的链接&lt;a class='btn' linked="clickMe"...

    【讨论】:

    • 考虑将 dispose 添加到指令并从中分离点击事件
    • 不错的 +1 对我来说是新的学习,很高兴知道可以在 angularjs 上模拟事件。但是,我不想依赖模拟单击另一个按钮。我想要的是模拟提交(因此在提交之前触发验证)。虽然我可以hide the button 在第一种形式上,但对我来说感觉很笨拙。如果有模拟提交+验证的 API 方式,我会非常乐意学习它,我会接受这个作为答案
    • 我认为如果你调用document.getElementById("myformId").submit(),它不会调用现代浏览器(HTML5)中“内置”的客户端验证。但是,如果您在模型中进行验证,它将起作用。但是,如果您这样做,您将支持所有浏览器,而不仅仅是现代浏览器。
    【解决方案2】:
        for (control of $scope.[form name].$$controls) {
            control.$setDirty();
            control.$validate();
        }
    

    你可以试试上面的代码。在提交之前让它运行。

    【讨论】:

    • 这对我有用。它触发控件上的验证器。尽管由于变量被传递给我的验证器,我不得不在摘要周期之后使用 $timeout 来运行它
    【解决方案3】:

    理想情况下,应该有一种编程方式使验证在表单中重新运行。我还没有完全调查过,但是有一种情况需要根据范围内的不同数据重新验证多个控件 - 无需用户与各个控件进行交互。这是因为表单有两个操作按钮,每个按钮在被点击时都需要不同的验证规则。

    在我完全实施强制重新验证之前,UI 要求发生了变化,但在此之前,我通过复制然后重新设置表单的数据获得了我需要的大部分内容。这强制在当前范围内对表单进行重新验证。基本上,它遵循以下内容(未经测试,但取自正在运行的代码)。在这种情况下,表单的数据绑定到一个对象的属性。

    var formData = $parse(<form's model>); 
    var dataCopy = angular.copy( formData($scope) ); 
    formData.assign( $scope, dataCopy );
    

    【讨论】:

      【解决方案4】:

      这可能会也可能不会接受,但如果您可以在表单完成之前禁用提交按钮,您可以这样做:

      <form name="formName">
       <input ng-required="true" />
      </form>
      <button ng-click="someFunction()" ng-disabled="formName.$invalid" />
      

      还值得注意的是,这在 IE9 中有效(如果您担心的话)。

      【讨论】:

        【解决方案5】:

        为您的表单命名:

        <div ng-controller="MyCtrl">
            <form name="myForm">
                <input name="myInput" />
            </form>
        </div>
        

        因此您可以在您的范围内访问您的表单验证状态。

        app.controller('MyCtrl', function($scope) {
            $scope.myForm.$valid // form valid or not
            $scope.myForm.myInput // input valid or not
            // do something with myForm, e.g. display a message manually
        })
        

        angular doc

        无法在表单之外触发浏览器表单行为。您必须手动执行此操作。

        【讨论】:

          【解决方案6】:

          由于我的表单字段仅在字段无效且已被用户触摸时才显示验证消息:

          <!-- form field -->
          <div class="form-group" ng-class="{ 'has-error': rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched && rfi.rfiForm.stepTwo.Parent_Suffix__c.$invalid }">
          
              <!-- field label -->
              <label class="control-label">Suffix</label>
              <!-- end field label -->
              <!-- field input -->
              <select name="Parent_Suffix__c" class="form-control"
                  ng-options="item.value as item.label for item in rfi.contact.Parent_Suffixes"
                  ng-model="rfi.contact.Parent_Suffix__c" />
              <!-- end field input -->
              <!-- field help -->
              <span class="help-block" ng-messages="rfi.rfiForm.stepTwo.Parent_Suffix__c.$error" ng-show="rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched">
                  <span ng-message="required">this field is required</span>
              </span>  
              <!-- end field help -->
          </div>
          <!-- end form field -->
          

          我能够使用由按钮触发的代码来显示我的无效字段:

          // Show/trigger any validation errors for this step
          angular.forEach(vm.rfiForm.stepTwo.$error, function(error) {
              angular.forEach(error, function(field) {
                  field.$setTouched();
              });
          });
          // Prevent user from going to next step if current step is invalid
          if (!vm.rfiForm.stepTwo.$valid) {
              isValid = false;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-11-02
            • 1970-01-01
            • 2023-04-02
            • 2011-04-21
            • 1970-01-01
            • 2011-11-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多