如何隔离嵌套表单?

时间:2014-08-19 16:25:32

标签: html angularjs

我是AngularJS的新手,也是客户端编程的新手。

上下文

我正在实施一个支持多个电话号码和地址的联系表格。

看起来像这样:

<form name="contactInsertForm" ng-controller="contactInsertController as contactCtrlr" ng-submit="contactInsertForm.$valid && contactCtrlr.save()">
    <input type="text" name="name" />
    <phones-editor></phones-editor>
    <addresses-editor></addresses-editor>
    <input type="submit" />
</form>

phonesEditoraddressesEditor是自定义Angular指令,可实现对添加,删除和编辑电话和地址的支持。控制器和模块如下所示:

地址:

(function () {
    var app = angular.module("AddressesEditorModule", []);
    app.directive("addressesEditor", function () {
        return {
            restrict: "E",
            templateUrl: "/addressesEditorTemplate.html",
            controller: function ($scope) {
                this.addresses = [
                    // this will hold addresses.
                ];

                // ...
            }
        }
})();

电话:

(function () {
    var app = angular.module("PhonesEditorModule", []);
    app.directive("phonesEditor", function () {
        return {
            restrict: "E",
            templateUrl: "/phonesEditorTemplate.html",
            controller: function ($scope) {
                this.phones = [
                    // this will hold phones.
                ];

                // ...
            }
        }
})();

模板:

地址:

<!-- list already added addresses -->
<div ng-repeat="address in addressesEditorCtrlr.addresses">
    <p>{{address.address}}</p>
    <p>{{address.city}}</p>
</div>
<form name="addressInsertForm" ng-submit="addressInsertForm.$valid && addressesEditorCtrlr.add()">
    <!-- inputs for each of the address fields -->
    <input type="submit" value="Add" />
</form>

电话:

<!-- list already added phones -->
<div ng-repeat="phone in phonesEditorCtrlr.addresses">
    <p>{{phone.number}}</p>
    <p>{{phone.areaCode}}</p>
</div>
<form name="phoneInsertForm" ng-submit="phoneInsertForm.$valid && phonesEditorCtrlr.add()">
    <!-- inputs for each of the phone fields -->
    <input type="submit" value="Add" />
</form>

您可能已经注意到,浏览器HTML生成的内容如下所示:

<form>
    <input type="text" name="name" />
    <phones-editor>
        <!-- list already added phones -->
        <div ng-repeat="phone in phonesEditorCtrlr.addresses">
            <p>{{phone.number}}</p>
            <p>{{phone.areaCode}}</p>
        </div>
        <form name="phoneInsertForm" ng-submit="phoneInsertForm.$valid && phonesEditorCtrlr.add()">
            <!-- inputs for each of the phone fields -->
            <input type="submit" value="Add" />
        </form>
    </phones-editor>
    <addresses-editor>
        <!-- list already added addresses -->
        <div ng-repeat="address in addressesEditorCtrlr.addresses">
            <p>{{address.address}}</p>
            <p>{{address.city}}</p>
        </div>
        <form name="addressInsertForm" ng-submit="addressInsertForm.$valid && addressesEditorCtrlr.add()">
            <!-- inputs for each of the address fields -->
            <input type="submit" value="Add" />
        </form>
    </addresses-editor>
</form>

问题:

我在form内有两个form。嵌套表单正常工作,添加和验证它应该执行的值,并拒绝添加无效的电话/地址。

但是当我单击外部表单上的submit按钮时,它将解释内部表单输入字段,如果这些字段具有无效值,则会引发错误。

如何使用AngularJS表单处理并避免这种情况?这有可能吗?

3 个答案:

答案 0 :(得分:2)

如果您希望将子表单作为隔离表单,则需要一个指令。看看this SO question的答案。请看this answer附带的小提琴。我正在为您提供小提琴链接js-fiddle以查看它的实际效果。

将代码放在下面只是因为SO不接受小提琴链接......

<form name="parent">
    <input type="text" ng-model="outside"/>
    <ng-form name="subform" isolate-form>
        <input type="text" ng-model="inside"/>
    </ng-form>
</form>

答案 1 :(得分:1)

article 正是您所需要的。

基本要点是您要在表单标记中使用 ngForm 指令。

<div ng-form="outerForm">
  <input type="text" ng-model="main.outerFormText"/>
  <div ng-form="innerForm">
    <input type="text" ng-model="main.innerFormText" required/>
    <button type="button" ng-click="main.submit('innerForm')"
      ng-disabled="innerForm.$invalid">Inner Submit</button>
  </div>
  <button type="button" ng-click="main.submit('outerForm')"
    ng-disabled="outerForm.$invalid">Outer Submit</button>
</div>

Example plnkr

答案 2 :(得分:1)

使用Angular 1.6

const isolatedFormDirective = () => {
    return {
        restrict: 'A',
        require: '?form',
        link: ($scope, $element, $attrs, ctrl) => {
            ctrl && ctrl.$$parentForm && ctrl.$$parentForm.$removeControl(ctrl);
        }
    }
}

app.directive('isolatedForm', isolatedFormDirective);