访问父数组以在ngMessages中进行唯一键验证

时间:2016-11-29 18:45:55

标签: angularjs validation custom-validators ng-messages

对于一组键值对({ key: 'keyName', value: 'value' }),我需要确保键在列表中是唯一的。我想利用ngMessages来显示消息。我正在使用Angular MaterialES6进行转录,但这不应该影响问题的实质。

基本问题是我不知道如何优雅地访问$validators管道中数组的其他项。以下是我当前自定义验证器的基本示例:

someModel.directive('unique', () => {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: ($scope, elem, attrs, ngModel) => {
      ngModel.$validators.unique = (currentKey) => {
        const otherItems = scope.$parent.$ctrl.items.slice(); // <== KLUDGE
        otherItems.splice($scope.$index, 1); // ignore current item
        return !otherItems.some(item => item.key === currentKey);
      };
    },
  };
});

这是视图模板的样子:

<md-list ng-form="$ctrl.keyValuePairs">
  <md-list-item ng-repeat="item in $ctrl.items track by $index">
    <!-- key -->
    <md-input-container>
      <input type="text" name="key_{{::$index}}" ng-model="item.key" required unique />
      <div ng-messages="$ctrl.keyValuePairs['key_'+$index].$error">
        <div ng-message="required">Required</div>
        <div ng-message="unique">Must be unique</div>
      </div>
    </md-input-container>

    <!-- value -->
    <md-input-container>
      <input type="text" name="val_{{::$index}}" ng-model="item.value" ng-required="item.key" />
      <div ng-messages="$ctrl.keyValuePairs['val_'+$index].$error">
        <div ng-message="required">Required if key is present</div>
      </div>
    </md-input-container>
  </md-list-item>
</md-list>

有效,但我不想1)知道集合的名称(items),2)通过{爬上{来访问它{1}}的父母。

1 个答案:

答案 0 :(得分:1)

simple yet effective解决方案是传入父数组。

someModel.directive('unique', () => {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: ($scope, elem, attrs, ngModel) => {
      ngModel.$validators.unique = (currentKey) => {
        const otherItems = $scope.$eval(attrs.unique); // <== FIX
        otherItems.splice($scope.$index, 1); // ignore current item
        return !otherItems.some(item => item.key === currentKey);
      };
    },
  };
});

缩写HTML:

<input type="text" name="key_{{::$index}}" ng-model="item.key" unique="{{$ctrl.items}}" />

h / t @msarchet