【问题标题】:How to trigger form submit programmatically in AngularJS?如何在AngularJS中以编程方式触发表单提交?
【发布时间】:2015-02-25 17:16:21
【问题描述】:

根据 Angular 的文档,ngSubmit 是提交表单的首选方式。所有挂起的操作都立即完成,并且$submitted 标志也被设置。而收听ngClick 事件则没有相同的效果。

现在我需要提交一个带有热键的表单,该表单具有ngSubmit 方法的所有优点。因此我需要一些方法来触发标准提交工作流。

我在 DOM 表单上尝试了 submit() 并且它有效,但是附加到范围的 angular 表单对象不包含对 DOM 表单的引用,因此我需要通过 jqLit​​e 访问它:

var frm = angular.element('#frmId');
frm.submit();

我不喜欢这种在控制器代码中访问 DOM 的解决方案,所以我创建了一个指令:

function wuSubmit() {
    return {
        require: 'form',
        restrict: 'A',
        link: function(scope, element, attributes) {
            var scope = element.scope();
            if (attributes.name && scope[attributes.name]) {
                scope[attributes.name].$submit = function() {
                    element[0].submit();
                };
            }
        }
    };
}

使用$submit 方法扩展表单对象。

由于未知原因,这两种变体都不起作用。 form.submit() 尝试发送数据,不阻止默认操作。


更新 1
事实证明,Angular 会监听具有type="input" 的元素的点击事件。
最终我决定触发该元素的点击事件:

wuSubmit.$inject = ['$timeout'];
function wuSubmit($timeout) {
    return {
        require: 'form',
        restrict: 'A',
        link: function (scope, element, attributes) {
            var submitElement = element.find('[type="submit"]').first();

            if (attributes.name && scope[attributes.name]) {

                scope[attributes.name].$submit = submit;
            }

            function submit() {
                $timeout(function() {
                    submitElement.trigger('click');
                });
            }
        }
    };
}

是否有针对此功能的开箱即用解决方案?

【问题讨论】:

  • 如何在 HTML 表单中绑定普通表单提交?

标签: javascript angularjs html forms


【解决方案1】:

你可以修改你的指令代码有点像:

function wuSubmit() {
    return {
        require: 'form',
        restrict: 'A',
        link: function(scope, element, attributes) {
            var scope = element.scope();
            if (attributes.name && scope[attributes.name]) {
                scope[attributes.name].$submit = function() {
                    // Parse the handler of submit & execute that.
                    var fn = $parse(attr.ngSubmit);
                    $scope.$apply(function() {
                        fn($scope, {$event: e});
                    });
                };
            }
        }
    };
}

在这里您不必在任何地方添加wu-submitng-submit 会起作用。

希望这会有所帮助!

【讨论】:

  • nope.. 问题不在于调用同一个处理程序。问题在于让 Angular 执行所有操作,就像实际提交发生时一样。
  • 您是说“执行所有操作”来执行验证和全部操作吗?
【解决方案2】:

只需在表单元素上使用事件 .triggerHandler('submit')。

myApp.directive("extSubmit", ['$timeout',function($timeout){
    return {
        link: function($scope, $el, $attr) {
            $scope.$on('makeSubmit', function(event, data){
              if(data.formName === $attr.name) {
                $timeout(function() {
                  $el.triggerHandler('submit'); //<<< This is Important

                  //equivalent with native event
                  //$el[0].dispatchEvent(new Event('submit')) 
                }, 0, false);   
              }
            })
        }
    };
}]);

http://jsfiddle.net/84bodm5p/

【讨论】:

    【解决方案3】:
    app.directive("form", function(){
         return {
            require: 'form',
            restrict: 'E',
            link: function(scope, elem, attrs, form) {
                form.doSubmit = function() {
                    form.$setSubmitted();
                    return scope.$eval(attrs.ngSubmit);
                };
            }
        };
    });
    

    HTML:

    <form name="myForm" ng-submit="$ctrl.submit()" novalidate>
    

    然后调用控制器

    $scope.myForm.doSubmit();
    

    【讨论】:

    • 这是一个新颖的解决方案,猴子补丁 ngFormController 添加一个doSubmit 方法。
    猜你喜欢
    • 1970-01-01
    • 2014-07-11
    • 2017-08-03
    • 2020-10-03
    • 2010-11-22
    • 1970-01-01
    • 2010-10-16
    • 2015-03-03
    • 1970-01-01
    相关资源
    最近更新 更多