将上下文作为参数传递给自定义验证器

时间:2018-03-22 12:35:06

标签: angular typescript

我尝试在自定义异步验证器中传递一个类属性,但当我从此验证器中记录它时,它的值仍然始终为undefined ...

来自CustomValidators.js:

static isValidPlace(place: Place, controlName: string): AsyncValidatorFn {
    return (control: FormControl): Observable<{ [key: string]: boolean }> => {
      console.log('control', control.value);
      console.log('place', place);

      if (place && place.label !== control.value)
        return Observable.of({ 'invalidPlace': true });

      return Observable.empty();
    }
}

来自组件:

city: FormControl = this.fb.control(
  '', 
  Validators.required, 
  CustomValidators.isValidPlace(this.citySelection, 'city').bind(this)
);

我在发射以下fn的字段上附加(更改)事件:

onSelectionCity = (selection: Place): Place => this.citySelection = selection;

问题:如何通过自定义验证程序传递更新的citySelection属性?

我想做什么:

当用户点击结果列表时,我需要一个由api发送的id,该结果列表本身取决于在formControl(输入)中输入的值。

问题是,当用户更改值时,我必须认为formControl无效,因为验证输入字段的唯一方法是单击列表以获取ID。同时如果值改变,id变得不正确,我想应用这种行为。

例如:想象一下Google搜索引擎与着名的“搜索”按钮略有不同。 事实上,当你在搜索字段中写一些内容并显示一个列表时。现在点击其中一个项目。

现在想象一下,按钮需要一个id来搜索正确的信息,这个id就是点击事件。

你的id很棒,但是更改文本,输入字段必须无效,因为你之前获得的ID与你潜在的新搜索要求不同。

我的建议是将包含label,id和保存在我的组件类上的其他东西selectionCity的完整对象与clickControl的实际值进行比较,以通过简单的三重比较确定有效性。

1 个答案:

答案 0 :(得分:1)

您应该在ID更改后重新创建表单控件或更新其验证程序,而不是尝试将组件绑定到验证程序。

onValueChange = () => {
  this.myForm.controls['controlName']
    .clearValidators() 
    .setValidators([
      Validators.required,
      CustomValidators.isValidPlace(this.citySelection, 'city')
  ]);
}