8

我有一个嵌套的 AngularJS 表单,如下所示:

<form name="parentForm" ng-submit="submit()">
    <input name="parentInput" type="text">
    <ng-include src="childForm.html" ng-form="childForm"></ng-include>
    <button type="submit">Submit</submit>
</form>

这是 childForm.html

<input name="childInput" type="text">

由于与问题无关的原因,我无法合并父表单和子表单 - 它们需要是两个单独的文件。

现在,当用户单击提交按钮时,验证正确地应用于 parentForm 和 childForm。但是,只有父表单的 $submitted 标志设置为 true,这是有问题的,因为我使用它来触发某些错误消息的显示。我不希望子表单检查父表单是否为 $submitted,因为它们是两个单独的文件。我想到的唯一选择是在子表单上调用 submit() 方法 $setSubmitted() ,这很尴尬,因为现在父表单需要直接引用子表单。有没有更好的方法将子表单的 $submitted 设置为 true?

4

4 回答 4

6

作为 Meeker 解决方案的扩展,您可以$broadcast通过向父表单添加手表来隐式实现:

.directive('form', function() {
  return {
    restrict: 'E',
    require:  'form',
    link: function(scope, elem, attrs, formCtrl) {

      scope.$watch(function() {
        return formCtrl.$submitted;
      }, function(submitted) {
        submitted && scope.$broadcast('$submitted');
      });
    }
  };
})

.directive('ngForm', function() {
  return {
    restrict: 'EA',
    require:  'form',
    link: function(scope, elem, attrs, formCtrl) {

      scope.$on('$submitted', function() {
        formCtrl.$setSubmitted();
      }); 
    }
  };
})
于 2015-05-09T10:44:38.870 回答
4

这个https://github.com/angular/angular.js/issues/10071在 Angular 的错误跟踪器中存在问题。与此同时,一条评论提出了这种解决方法:

// sets all children ng-forms submitted (no such default functionality)
function setSubmitted(form) {
    form.$setSubmitted();
    angular.forEach(form, function(item) {
        if(item && item.$$parentForm === form && item.$setSubmitted) {
            setSubmitted(item);
        }
    });
}

// so ie. instead of scope.form.$setSubmitted(); use:    
setSubmitted(scope.form);

这种方法的一个问题是任何动态添加的表单都不会复制其父级的初始状态。我在动态添加表单时使用它:

function onNewChildForm (form) {
    if(form.$$parentForm && form.$$parentForm.$submitted) {
        setFormSubmitted(form);
    }
}
于 2016-01-25T14:44:20.447 回答
2

这是我对这个问题的解决方案(我打赌有人可以让这个更漂亮)

我做了一个附加监听器的 ngForm 指令,

.directive('ngForm', function(){
    return {
        restrict: 'AE',
        require: 'form',
        link: function(scope,element,attrs,form){
            var parentForm = element.parent().controller('form');
            if(parentForm){
                scope.$on('parentFormSubmitted',function(event){
                    form.$setSubmitted();
                });
            }
        }
    };
})

然后在父表单的控制器中,我在提交表单时执行这段代码

$scope.submit = function(){
  $scope.$broadcast('parentFormSubmitted');
}
于 2014-09-30T21:15:30.390 回答
0

我最初使用 Scarlz 的解决方案,但在我的情况下,我有几个ng-formng-if.

我没有使用ng-show和处理可能存在的数据,而是修改了 Scarlz 的解决方案以使用提交事件而不是查看form.$submitted属性

  function ParentFormThatSubmits() {
    return {
      restrict: 'E',
      require: 'form',
      link: function(scope, elem, attrs, formCtrl) {
        elem.on('submit', function() {
          var submitted = formCtrl.$submitted;
          if(submitted) {
            scope.$broadcast('$submitted');
          }
        });
      }
    };
  }

  function ChildFormThatSubmits() {
    return {
      restrict: 'EA',
      require: 'form',
      link: function(scope, elem, attrs, formCtrl) {
        scope.$on('$submitted', function() {
          formCtrl.$setSubmitted();
          scope.$apply();
        });
      }
    };
  }

  angular.module('appModule')
    .directive('form', ParentFormThatSubmits)
    .directive('ngForm', ChildFormThatSubmits);

于 2017-05-16T17:07:30.320 回答