Ошибка пользовательского валидатора Angular 6 Reactive Forms, отображаемая из его собственных данных - PullRequest
0 голосов
/ 19 октября 2018

У меня есть FormArray в FormGroup, и каждый из FormArray имеет несколько FormGroup и может добавлять их динамически.

У меня есть Custom Validator, где он проверяет все данные в каждом из FormArray для проверкиповторение данных. С этим связана проблема: одна FormGroup в FormArray сравнивает ее со всеми данными в FormArray и возвращает True, поскольку FormGroup существует внутри FormArray

Ссылка StackBlits: https://stackblitz.com/edit/angular-custom-validator-defaultdata

Шаги проблемы: Нажмите на дополнительное назначение => Выберите позицию, отдел и местоположение, как в предыдущем ряду.=> Вы увидите ошибку «Данные того же задания» => Теперь измените значение Позиции на что-то другое => Нет ошибки => Измените значение на входе Pay Rate => Вы видите ошибку «Та же работа»data "> Поскольку он сравнивает измененную строку с данными из данных формы, которые определенно вернут значение True.

Можно ли как-то ограничить возникновение ошибки при проверке собственных данных?

Я проверяю только сходство между Положением, Отделом и Местоположением.

for (let assign of this.additionalAssign) {
      const fg = new FormGroup({
        "payRate": new FormControl(assign.jobRate, Validators.required),
        "position": new FormControl(assign.position, Validators.required),
        "location": new FormControl(assign.location, Validators.required),
        "department": new FormControl(assign.department, Validators.required)
      }); 
      fg.validator = this.jobDataValidator.bind(this);
      this.addPay.push(fg);
    }

Валидатор:

jobDataValidator(control: FormControl): {[s: string]: boolean} {
    let value = this.getJobLocDeptValidity(control);
    if(value.length > 0 && control.dirty){
      return {'sameJobData': true};
    }
    return null;
  }

  getJobLocDeptValidity(control: FormControl):any[] {
    let additionalAssignments = this.additionalAssignmentsForm.value.payArray;
    let test = additionalAssignments.filter(item =>  !!control.value.position && item.position === control.value.position && !!control.value.department && item.department === control.value.department && !!control.value.location && item.location === control.value.location);
    return test;
  }

Изображение 1: Данные новой строки (3-ий)то же, что и предыдущий (2-й) => Отображаемая ошибка Same data as previous one

Изображение 2. Изменение значения выбора позиции и исчезновение ошибки Position changed and Error Disappears

Изображение 3: Введите какое-то число в поле ввода Pay Pay, и снова появится сообщение об ошибке.Input payrate changes and Error Appears

Ответы [ 3 ]

0 голосов
/ 19 октября 2018

Я разбудил ваше приложение и внес некоторые незначительные изменения в код.сейчас работает как положено.Пожалуйста, смотрите на stackblitz .

Я сделал три изменения, которые перечислены ниже:

  1. У вас нет никакого uniqueid на уровне строки, я добавилкак индекс вашей 'this.addPay' длины.См. Строки № 57 и 75.
  2. применяемое условие в методе 'getJobLocDeptValidity' для проверки индекса текущего элемента управления и индекса фильтра не должно быть одинаковым и внесло некоторые другие изменения.

Вот изменения кода вашего getJobLocDepValidity.

 getJobLocDeptValidity(control: FormControl):any[] {
    let additionalAssignments = this.additionalAssignmentsForm.value.payArray;
    let test = additionalAssignments.filter(item => {
if(control.value.index != item.index){
return (item.payRate == control.value.payRate && item.position == control.value.position && item.department == control.value.department && item.location == control.value.location)
}
return false;
    } );
    return test;
  }

@ Sunil Я бы посоветовал, пожалуйста, попробуйте дать правильный ответ и проверить его, прежде чем давать свои входные данные, так что кто-то может легко реализоватьбез какого-либо глючного кода.

0 голосов
/ 19 октября 2018

Вы можете попробовать исключить значение payRate из валидатора следующим образом:

jobDataValidator(control: FormControl): {[s: string]: boolean} {
    let value = this.getJobLocDeptValidity(control);
    if(value.length > 0 && control.dirty  && !control.value.payRate){
      return {'sameJobData': true};
    }
    return null;
  }
0 голосов
/ 19 октября 2018

Ваша реализация выглядит отлично, за исключением условия проверки.Так как у вас нет уникального идентификатора для строки, его трудно сопоставить, если запись уже существует или сейчас.

Однако вам повезло иметь ссылку на все необходимые объекты.Вы можете проверить, соответствует объект или нет.

Просто добавьте еще одно условие в часть проверки

control !== item 

Ниже приведен измененный код -

  getJobLocDeptValidity(control: FormControl):any[] {

    let additionalAssignments = this.additionalAssignmentsForm.value.payArray;
    let test = additionalAssignments.filter(item =>  
    control !== item && !!control.value.position && item.position === control.value.position && !!control.value.department && item.department === control.value.department && !!control.value.location && item.location === control.value.location);
    return test;
  }

Обновить

Поскольку у вас есть index и согласно вашему комментарию, проверка ниже работает.

control.index !== item.i
...