【问题标题】:Triggering form validation programmatically in angular-js在 angular-js 中以编程方式触发表单验证
【发布时间】:2017-02-11 14:35:56
【问题描述】:

我正在使用自定义指令以编程方式提交表单,但是在提交表单之前未应用表单验证。我在表单域上调用了$setDirty(),在表单上调用了$setSubmitted(),但即使所需的表单域为空,表单仍会提交。

指令/external.submit.js

export default class externalSubmit {
    constructor ($timeout) {
        'ngInject';
        this.$timeout = $timeout;
        this.restrict = 'A';
        this.scope = {};
    }

    link($scope, $element, $attrs) {
        $scope.$on('submit-form', function(event, data){
            if( data.id === $attrs.id ) {
              setTimeout(function() {

              /**
              * set form and fields to dirty
              * this should be enabling validation
              **/
              var $formScope = angular.element($element).scope();
              var $formController = $formScope[formName];

              $formController.$setDirty();
              $formController.$setSubmitted();
              angular.forEach($formController.$error.required, function(field) {
                field.$setDirty();
              });

                // trigger form submit
                $element.triggerHandler('submit');
              }, 0);   
            }
        });
    }

    // Create an instance so that we can access this inside link
    static factory() {
        externalSubmit.instance = new externalSubmit();
        return externalSubmit.instance;
    }
};

foo/foo.controller.js

export default class FooController {
    constructor( $rootScope ) {
      'ngInject';

      this.$rootScope = $rootScope;
      this.item = {};   

    }

    save() {
      alert('Save triggered');
    }

    submitForm(id) {
        // if no form id given, use the first form in the content area
        if ( ! id ) id = $('form')[0].id;
        this.$rootScope.$broadcast('submit-form',{'id':id} );
    }

}

foo/foo.html

<form external-submit id="primary" ng-submit="$ctrl.save()" go-back="dashboard.home()">
    <input type="hidden" ng-model="$ctrl.item.id"/>
    <input required name="title" ng-model="$ctrl.item.title" type="text" />
    <button type="submit">Internal Submit</button>
</form>

<button type="submit" ng-click="$ctrl.submitForm()">External Submit</button>

【问题讨论】:

  • 为什么代码会注入 $timeout 却使用原始的setTimeout 来代替? $timeout 正确包装 setTimeout 并与 AngularJS 摘要循环集成。使用原始 setTimeout 似乎有问题。
  • 啊。因为我得到一个 $timeout 不是函数错误。在构造函数中将$timeout 打印到控制台表明它是undefined。有什么想法吗?

标签: javascript angularjs angularjs-directive ecmascript-6 angular-validation


【解决方案1】:

使用ng-submit="$valid &amp;&amp; $ctrl.save()"

【讨论】:

  • 好的,这会触发表单验证,但是当我的字段有效时,$ctrl.save() 永远不会被调用——无论是使用内部按钮还是外部按钮。
【解决方案2】:

解决方案是在触发submit 处理程序之前检查$formController 以查看表单是否有效。

link($scope, $element, $attrs, $ctrl ) {      

    $scope.$on('submit-form', function(event, data){

        if( data.id === $attrs.id ) {
          let formName = $attrs.name;
          setTimeout(function() {

            // get the element scope
            var $formScope = angular.element($element).scope();

            // get the form controller using the form name
            var $formController = $formScope[formName];
            $formController.$setSubmitted();

            // check if form is valid before triggering submit
            if ( $formController.$valid ) {
                $element.triggerHandler('submit');
            }

            // required to update form styles
            $scope.$apply();

          }, 0);   
        }
    });
}

【讨论】:

    猜你喜欢
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多