просто добавьте аргументы в функцию Validator
private validator(indexInArray:number): ValidatorFn { //<--here
return (abstractControl: AbstractControl) => {
//you can use indexInArray here
if (indexInArray==0) //For the first give always valid
return null;
//I change this.items by this.form.value
const lenOfPrev = this.form.value[indexInArray - 1].value.length
if (abstractControl.value.length <= lenOfPrev.length) {
return {
notLargeEnough: 'should be bigger'
}
}
return null
}
}
Но, если вы используете значения компонента, вам нужно "связать" валидатор
this.items.forEach((item, i) => {
const previousControl = i > 0 ? inputs.controls[i - 1] : null;
inputs.push(this.fb.control(
item.value,
this.validator(i).bind(this), //<--see the argument and the "bind"
this.asyncValidator(),
));
});
Но, извините , Этот подход имеет соответствующий недостаток: что произойдет, если вы измените, например, 2-й вход с «ааа» на «ааааа» ?. Если ваш 3-й вход «bbbb», то до того, как он был действителен, но не после изменения. Но Angualr может принять это, потому что 3-й вход не меняется. Итак, почему бы не использовать Validator для всех formArray. Как пользовательский валидатор возвращает объект, вы можете вернуть, например, массив [false, false, true, false] и спросить об этом значении
private validatorArray()
{
return (formArray:FormArray)=>{
if (!formArray.value)
return null;
const result= (formArray.value.map((x:any,i:number)=>{
if (i==0)
return false;
return (x.length<=formArray.value[i-1].length)
}))
return result.find(x=>x)?{error:result}:null;
}
}
В form.errors?.error[i]
у вас есть, если элемент управления недействителен
Вы можете увидеть два подхода в этот стек стека
ПРИМЕЧАНИЕ: я использую непосредственно formArray FormControls, но это тот же
Upate после прочтения ответа Курта, на самом деле это не обязательно bind (this) в валидаторе, просто передайте предыдущий элемент управления, как сказал Курт.