Angular 2 个带有可观察参数的自定义验证器

Angular 2 Custom Validator with Observable Parameter

我有这个自定义验证器:

export const mealTypesValidator = (mealSelected: boolean) => {
    return (control: FormControl) => {
        var mealTypes = control.value;
        if (mealTypes) {
            if (mealTypes.length < 1 && mealSelected) {
                return {
                    mealTypesValid: { valid: false }
                };
            }
        }
        return null;
    };
};

如果我这样使用它,它会起作用:

ngOnInit() {
    this.findForm = this.formBuilder.group({
        categories: [null, Validators.required],
        mealTypes: [[], mealTypesValidator(true)],
        distanceNumber: null,
        distanceUnit: 'kilometers',
        keywords: null,
    });
}

要注意的是,mealSelected 是我组件上的一个 属性 - 当用户选择和取消选择一餐时它会改变。

我如何调用上面的验证器是使用永远不会改变的静态 true。

当我使用 component.mealSelected 值作为参数时,如何让验证器工作,例如:

ngOnInit() {
    this.findForm = this.formBuilder.group({
        categories: [null, Validators.required],
        mealTypes: [[], mealTypesValidator(this.mealSelected)],
        distanceNumber: null,
        distanceUnit: 'kilometers',
        keywords: null,
    });
}

因为如果我像上面那样做,它会立即评估 this.mealSelected 这在当时是错误的 - 然后当用户选择一顿饭时,它不会继续并将 true 传递给自定义验证者。

解决方案是将验证器移到我的组件中并使用 this.mealSelected 进行检查。然后我遇到了一个问题,当一顿饭 selected/deselected 时验证器没有被触发,我使用 this.findForm.controls['mealTypes'].updateValueAndValidity(); 来触发验证。

代码(可以重构以从自定义验证器中删除参数):

ngOnInit() {
    this.findForm = this.formBuilder.group({
        categories: [null, Validators.required],
        mealTypes: [[], this.mealTypesValidator(true)],
        distanceNumber: null,
        distanceUnit: 'kilometers',
        keywords: null,
    });
}

mealTypesValidator = (mealSelected: boolean) => {
    return (control: FormControl) => {
        var mealTypes = control.value;
        if (mealTypes) {
            if (mealTypes.length < 1 && this.mealSelected) {
                return {
                    mealTypesValid: { valid: false }
                };
            }
        }
        return null;
    };
};

但是如果能够有一个单独的验证模块来集中验证,那还是很好的,所以如果有人知道如何拥有一个不断变化的参数值,比如一个组件字段作为自定义验证器的参数 - 就像我最初问的那样,那么我会很感激与该技术相关的答案。