Forms 使用动态生成表单输入进行验证时遇到的问题?

Forms 使用动态生成表单输入进行验证时遇到的问题?,forms,angularjs,validation,angularjs-directive,Forms,Angularjs,Validation,Angularjs Directive,我有一些基本的表单/输入html,如果显式编写如下,它们可以工作(包括验证): <form name="forms.create" novalidate> <div class="si-container"> <div class="si-input-container"> <input class="si-input" name="someNum" placeholder="Enter a number"

我有一些基本的表单/输入html,如果显式编写如下,它们可以工作(包括验证):

<form name="forms.create" novalidate>
    <div class="si-container">
        <div class="si-input-container">
            <input class="si-input" name="someNum" placeholder="Enter a number" ng-model="formdata.number" type="number" min="40"/>
        </div>
        <div class="si-error">
            <div ng-show="forms.create.someNum.$error.min">Error! Value must be > 40.</div>
        </div>
    </div>
</form>
.directive('specialInput', [function(){
    return {
        compile: function(elem, attrs){

            var input = angular.element('<input class="si-input"/>');

            input.attr('placeholder', attrs.placeholder);
            input.attr('type', attrs.type);
            input.attr('name', attrs.name);
            input.attr('ng-model', attrs.ngModel);

            var errorCont = angular.element('<div class="si-error"></div>');

            var errors = elem.children();
            angular.forEach(errors, function(error){
                var err = angular.element(error);
                var type = err.attr('error-type');
                var value = err.attr('error-value');
                input.attr(type, value);

                var formName = elem.parent().attr('name');
                errorCont.append('<div ng-show="' + formName + '.' + attrs.name + '.$error.' + type + '">' + err.html() + '</div>');
            });

            var cont = angular.element('<div class="si-container"></div>');
            cont.append('<div class="si-floating-label">' + attrs.placeholder + '</div>');
            cont.append('<div class="si-input-container">' + input[0].outerHTML + '</div>');
            cont.append('<div class="si-underline"></div>');  
            cont.append(errorCont);              

            elem.replaceWith(cont[0].outerHTML);
        }
    };
}]);
现在,使用上述指令生成的html看起来差不多正确。如果我将
{{formdata.number}}
放在表单下方,则值会按预期更改。问题是,现在验证从未显示出来

例如,如果我在输入中输入值
5
,然后检查表单对象,就会得到奇怪的结果<对于
表单
,code>$dirty设置为true,但对于
表单.someNum
则不设置为true。如果我在输入中输入
55
,则
表单的
$dirty
仍然设置为false。someNum
,但
$modelValue
$viewValue
都显示55

有什么想法或建议吗?这里有一个帮助您进行任何测试。 如果在输入框中输入50,您应该会看到下面的值,但输入5,则不会出现错误


更新

通过将dom更改移动到link函数而不是compile函数中,并添加以下内容,我成功地使其工作:

elem.replaceWith(cont);
$compile(cont)(scope);

但是我仍然很困惑,为什么这样做有效,而在编译函数中以完全相同的方式修改dom却不起作用。有人能解释这一点吗?

这是因为原始的
ng模型
仍然被编译,即使在编译函数中原始的DOM已经被新的DOM替换

ng model
指令将在其postLink函数中将自身注册到父窗体。由于postLink函数将反向执行(子对象在父对象之前),因此新的
ng模型将首先进行注册,因此它最终将被原始
ng模型的注册覆盖

为了避免此问题,您可以将原始的
ng model
更改为另一个名称,例如
my model
,然后在稍后的编译函数中将其重命名为
ng model

示例JSFIDLE:


希望这能有所帮助。

谢谢你的回答。
elem.replaceWith(cont);
$compile(cont)(scope);