angularjs parent ng-form即使在指令ng-form无效时也有效

时间:2014-04-05 08:12:30

标签: angularjs angularjs-directive

我已经编写了一个从范围字段生成输入字段的指令,一切正常,除非父ng表单保持无效,即使指令中的ng-form无效。

这是我如何检查表格的状态:

<ng-form name="parentForm" class="form-horizontal">
    <form-field ng-model="input.name" field="fields[0]" ng-change="changed(input.name)"></form-field>
    <form-field ng-model="input.age" field="fields[1]"></form-field>
    <pre> parent form: valid : {{parentForm.$valid}}</pre>
</ng-form>

以下是链接功能

var linkFunction = function (scope, element, attrs) {
    var fieldGetter = $parse(attrs.field);
    var field = fieldGetter(scope);
    var template = input(field, attrs); //genrate the template
    element.replaceWith($compile(template)(scope)); //replace element with templated code
};

我想问题是我需要编译父元素而不是元素本身才能使验证工作,但不确定如何操作

      element.replaceWith($compile(template)(scope));

PLUNKER LINK

1 个答案:

答案 0 :(得分:7)

根据 FormController 上的文档,有$addControl()方法用于:

使用表单注册控件 使用ngModelController的输入元素在链接时自动执行此操作。

这给了我们提示&#34; ng-model ed&#34;只要我们给他们机会,元素就会处理他们链接功能中的所有内容。给予他们机会(在此上下文中)意味着他们应该能够在链接时找到他们的父ngForm元素。
你已经(非常小心)剥夺了他们的权利,首先编译链接它们,然后将它们插入DOM (羞辱你)。 / p>

一旦你知道原因,解决方案很简单:
您需要先将它们插入DOM,然后将它们链接起来 E.g:

// Instead of this:
element.replaceWith($compile(template)(scope));

// Which is equivalent to this:
var linkFunc = $compile(template);   // compiling
var newElem  = linkFunc(scope);      // linking
element.replaceWith(newElem);        // inserting

// You should do this:
var newElem = angular.element(template);   // creating
element.replaceWith(newElem);              // inserting
$compile(newElem)(scope);                  // compiling + linking
                                           // (could be done in 2 steps
                                           //  but there is no need)

另请参阅此 short demo