Javascript 使用字段组时的角度形式错误摘要
希望这将是一个更通用的Angular JS问题,而不是Angular Formly特有的问题 我一直遵循为在Angle formly表单上构建错误摘要而提供的框架。一切都很好…但是 在示例中,他们的模型如下所示:Javascript 使用字段组时的角度形式错误摘要,javascript,angularjs,angular-formly,Javascript,Angularjs,Angular Formly,希望这将是一个更通用的Angular JS问题,而不是Angular Formly特有的问题 我一直遵循为在Angle formly表单上构建错误摘要而提供的框架。一切都很好…但是 在示例中,他们的模型如下所示: vm.fields = [ { key: 'picky', type: 'customInput', templateOptions: { label: 'Picky field...', placeholder: 'This is
vm.fields = [
{
key: 'picky',
type: 'customInput',
templateOptions: {
label: 'Picky field...',
placeholder: 'This is required and has a maxlength of 5 and minlength of 3',
required: true,
maxlength: 5,
minlength: 3
}
},
.....
{
key: 'ip',
type: 'customInput',
validators: {
ipAddress: {
expression: function(viewValue, modelValue) {
var value = modelValue || viewValue;
return /(\d{1,3}\.){3}\d{1,3}/.test(value);
},
message: '$viewValue + " is not a valid IP Address"'
}
},
templateOptions: {
label: 'IP Address',
required: true,
type: 'text',
placeholder: '127.0.0.1',
}
}
];
然后,如果我们查看HTML,我们可以看到这些字段被传递到错误摘要中,如下所示:
<formly-error-summary form="vm.form" fields="vm.fields"></formly-error-summary>
编辑 好的,在听取了下面Ken的建议之后,我已经能够修改我的formlyErrorSummary指令,这样它现在至少能够得到模型的错误。自从$scope以来,它有很多问题。$watch正在进行深层次的比较,甚至在第一个页面加载时,整个事件都会被触发3次!我已经添加了一些基本的转义来尝试和解决这个问题,至少现在我有错误,下一个问题是在HTML中,我调用
ng repeat=“field in vm.fields”
,这实际上是同一个问题,那么我如何解决这个问题呢?我的一部分想法是使用一些匿名对象来保存字段消息,以及字段消息是否有效,然后在HTML中解析这些消息,但我不确定这种想法是否适用于Angular
controller: function($scope) {
var vm = this;
$scope.$watch('vm.fields', function(){
for(var i = 0; i < vm.fields.length; i++)
if(vm.fields[i].fieldGroup) {
for(var j = 0; j < vm.fields[i].fieldGroup.length; j ++)
if(vm.fields[i].fieldGroup[j].formControl) {
var err = getErrorAsList(vm.fields[i].fieldGroup[j]);
if(err)
vm.getErrorAsList = err;
}
}
}, true);
然后,在指令模板中,我必须删除vm.fields
引用,因为在这种方法中这显然不起作用。因为我知道只有在表单被invlay时才会显示此摘要,所以我可以删除正在执行的其他检查,并最终以以下HTML结束:
<div class="row">
<div class="col-xs-12">
<div class="formly-error-summary bg-danger" ng-if="vm.form.$invalid">
<div ng-repeat="err in vm.errs" class="color-error">
<i class="glyphicon glyphicon-remove"></i>
<span>
{{err}}
</span>
</div>
</div>
</div>
</div>
{{err}}
我仍然不是100%满意这一点,它完成了任务,但我不确定这是否是“角度”的方式,以及我正在使用$scope.$watch
对fields对象有点让我的开发人员OCD恼火,但解决方案是一样的
如果有人对此有任何改进或建议,请让我知道,但这是一次非常有趣的学习体验 我认为最好的方法是将字段作为
vm.fields
传递,然后在指令中您可以自己处理获取子字段的所有错误。@谢谢您的建议,现在的问题是,如果我只传递vm.fields,那么getErrorAsList函数永远不会启动,只有当我传入一个列表,其中的字段已经可以访问时,它才会触发。$scope.$watch('vm.fields')
then;-)但是,在阵列上使用$watch时,您必须使用深度监视,并且根据一些文档,以这种方式监视整个阵列可能会对性能产生潜在影响。我也看不出这是如何绕过原始问题的,无法区分字段组和其中包含的字段?我已经用我认为可能的解决方案对问题进行了编辑,@kentcdoffics,如果您对此有任何意见,我欢迎,对于formly,我不太确定我是否以最有效的方式完成了这项工作,但它现在似乎仍然有效:)
angular.module("formlyApp").directive('formlyErrorSummary', function() {
return {
scope: {},
bindToController: {
form: '=',
fields: '='
},
templateUrl: 'js/Directives/formly-error-summary.html',
controllerAs: 'vm',
controller: function() {
var vm = this;
vm.getErrorAsList = getErrorAsList;
console.log(vm.fields);
function getErrorAsList(field) {
return Object.keys(field.formControl.$error).map(function(error) {
// note, this only works because the customInput type we have defined.
return field.data.getValidationMessage(error);
}).join(', ');
}
}
};
});
controller: function($scope) {
var vm = this;
$scope.$watch('vm.fields', function(){
for(var i = 0; i < vm.fields.length; i++)
if(vm.fields[i].fieldGroup) {
for(var j = 0; j < vm.fields[i].fieldGroup.length; j ++)
if(vm.fields[i].fieldGroup[j].formControl) {
var err = getErrorAsList(vm.fields[i].fieldGroup[j]);
if(err)
vm.getErrorAsList = err;
}
}
}, true);
vm.errs = [];
$scope.$watch('vm.fields', function(){
vm.errs = [];
for(var i = 0; i < vm.fields.length; i++)
if(vm.fields[i].fieldGroup) {
for(var j = 0; j < vm.fields[i].fieldGroup.length; j ++)
if(vm.fields[i].fieldGroup[j].formControl) {
var err = getErrorAsList(vm.fields[i].fieldGroup[j]);
if(err)
if(vm.errs.indexOf(err) === -1)
vm.errs.push(err);
}
}
}, true);
<div class="row">
<div class="col-xs-12">
<div class="formly-error-summary bg-danger" ng-if="vm.form.$invalid">
<div ng-repeat="err in vm.errs" class="color-error">
<i class="glyphicon glyphicon-remove"></i>
<span>
{{err}}
</span>
</div>
</div>
</div>
</div>