Forms 使用动态生成表单输入进行验证时遇到的问题?
我有一些基本的表单/输入html,如果显式编写如下,它们可以工作(包括验证):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"
<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);