我正在动态创建表单内的输入。我为此目的创建了这个指令:
// Generate inputs on the fly using BE data.
.directive('inputGenerator', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: {
id: '@',
type: '@',
name: '@',
attributes: '=',
ngModel: '=',
ngDisabled: '='
},
link: function (scope, iElement, iAttrs) {
// Get attributes
var id = iAttrs.id,
type = iAttrs.type,
name = iAttrs.name;
scope.ngModel[name] = {};
var extended_attributes = {
"type": type,
"id": id,
"data-ng-model": 'ngModel.' + name + '[\'value\']',
"name": name,
"data-ng-disabled": "ngDisabled"
};
if ( ! scope.attributes) {
scope.attributes = {};
}
// Append extra attributes to the object
angular.extend(scope.attributes, extended_attributes);
// Generate input
var input = '<input ';
angular.forEach(scope.attributes, function (value, key) {
input += key + '="' + value + '" ';
});
input += '/>';
// Compile input element using current scope (directive) variables
var compiledElement = $compile(input)(scope);
// Set the file selected name as the model value
compiledElement.on('change', function () {
if (this.files && this.files[0].name) {
var that = this;
scope.$apply(function () {
scope.ngModel[name] = {};
scope.ngModel[name]['value'] = that.files[0].name;
});
}
});
// Replace directive element with generated input
iElement.replaceWith(compiledElement);
}
};
}]);
此html行将触发指令:
<input-generator data-name="{{ item.name }}" data-ng-model="inputs.sources" data-attributes="item.attrs" data-type="{{ item.type }}" data-id="inputFile_{{ $index }}" data-ng-disabled="inputs.sources[item.name].selected" />
我正在使用Angular 1.4.3。
问题
模型和几乎一切都在指令中正常工作,但由于某种原因,当添加的输入无效时,表单仍然有效,如图所示。
我已经尝试过:
表单验证的任何Angular功能都可以使用
我调试了Angular,似乎附加到表单的输入与指令中编译的输入不同。
我在每个输入创建后都已调用formName.$setPristine()
,但它不起作用。
我无法从指令中访问该表单,但我认为也不是一个好主意。
我已经用ng-form标签包装了输入,但没有任何用处。
我尝试使用指令编译方法,但这只是在应用程序加载时触发一次,并且我有一个选择输入,在更改时加载不同的输入。
对此有任何帮助非常感谢! :)
感谢大家的贡献!
答案 0 :(得分:1)
你一定要看看我的Angular-Validation Directive/Service。它作为大量的功能,我也支持动态输入验证,你也可以传递一个隔离的范围,如果你不仅要有动态输入,还要有动态形式,这也有助于在模态窗口内使用。
例如,让我们将此示例作为动态表单和Controller中定义的输入:
$scope.items.item1.fields = [
{
name: 'firstName',
label:'Enter First Name',
validation:"required"
},
{
name: 'lastName',
label: 'Enter Last Name',
validation:"required"
}
];
$scope.items.item2 = {
heading:"Item2",
formName:"Form2"
};
$scope.items.item2.fields = [
{
name: 'email',
label:'Enter Email Id',
validation:"required"
},
{
name: 'phoneNo',
label: 'Enter Phone Number',
validation:"required"
}
];
它会将验证绑定到元素上,如果您想直接从Controller中检查表单有效性,只需使用此
var myValidation = new validationService({ isolatedScope: $scope });
function saveData() {
if(myValidation.checkFormValidity($scope.Form1)) {
alert('all good');
}
}
您也可以使用插值
<input class="form-control" type="text" name="if1"
ng-model="vm.model.if1"
validation="{{vm.isRequired}}" />
或者使用收音机/复选框启用/禁用在启用时仍要验证的字段:
ON <input type="radio" ng-model="vm.disableInput4" value="on" ng-init="vm.disableInput4 = 'on'">
OFF <input type="radio" ng-model="vm.disableInput4" value="off">
<input type="text" name="input4"
ng-model="vm.input4"
validation="alpha_dash|min_len:2|required"
ng-disabled="vm.disableInput4 == 'on'" />
它确实具有很多功能,可在Bower
和NuGet
上使用(标记名为angular-validation-ghiscoding
)。所以,请查看我的图书馆Angular-Validation以及 PLUNKER 的现场演示。
它已经加载了功能(自定义正则表达式验证器,AJAX远程验证,验证摘要,备用文本错误,使用服务即时验证等)。因此,请务必检查Wiki Documentation ......最后,使用量角器进行全面测试(超过1500个断言),所以不要害怕在生产中使用。
请注意我是这个图书馆的作者
答案 1 :(得分:1)
我和Angular v1.5.9一起遇到了这个问题。这里的主要问题是你正在编译HTML模板之前它在DOM中,因此Angular不知道它是表单的一部分。如果先添加HTML,然后编译,Angular会将您的输入视为表单子项,并将在表单验证中使用。
查看Form Validation and fields added with $compile
的类似答案不要这样做:
var myCompiledString = $compile(myHtmlString)(scope);
// ...
element.replaceWith(myCompiledString);
请改为:
var myElement = angular.element(myHtmlString)
element.replaceWith(myElement) // put in DOM
$compile(myElement)(scope) // $compile after myElement in DOM
注意:我将更常规的element
替换为OP的iElement
,这是指令的HTML元素的jQLite引用
答案 2 :(得分:0)
您需要使用ng-form指令作为输入的包装。
您可以看到此here
的示例答案 3 :(得分:0)
但它对我有用。您可以将表单引用传递给指令并直接使用它。
在下面的代码中,scope.form用于了解表单的一般状态,scope.name用于访问输入字段状态。
&LT; ng-form name =&#34; {{name}}&#34; ng-class =&#34; {error:this [name] [name]。$ invalid&amp;&amp;形式为$提交}&#34; &GT;
我希望它有所帮助
答案 4 :(得分:0)
您需要设置控件动态名称,并使用此动态名称进行表单验证。在以下例如你看到控制的动态名称和id,用于角度验证(使用ng-massages) 更多详情请参阅http://www.advancesharp.com/blog/1208/dynamic-angular-forms-validation-in-ngrepeat-with-ngmessage-and-live-demo
字段数是必需的。