Javascript 使用字段组时的角度形式错误摘要

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

希望这将是一个更通用的Angular JS问题,而不是Angular Formly特有的问题

我一直遵循为在Angle formly表单上构建错误摘要而提供的框架。一切都很好…但是

在示例中,他们的模型如下所示:

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>