具有动态值的最大值验证器
Maximum value validator with dynamic value
我有一项服务,其中 returns 用户拥有的代表金钱的价值,我希望用户能够以等于或小于总金额的价值进行交易。我试过像这样使用最大验证:
valid() {
const form: FormGroup = this._fb.group({
fond: ['', [Validators.required]],
serie: ['', [Validators.required]],
account: ['', [Validators.required, Validators.min(1)]],
value: ['', [Validators.required, Validators.min(1)]],
subAccount: ['', [Validators.required, Validators.min(1)]]
});
return form;
}
但是不行,好像max()
中的值必须从一开始就设置,所以它会假定totalAmount为undefined。
更新您已编辑的问题:
使用这个:
value: ['', [
Validators.required,
Validators.min(1),
(control: AbstractControl) => Validators.max(this.totalAmount)(control)
]]
您可以使用以下语法实现:
(control: AbstractControl) => Validators.max(this.totalAmount)(control)
为什么?
- 当您提供
Validators.max(this.totalAmount)
时,它会使用给定参数(this.totalAmount
的当前值)创建一个验证函数,然后将其分配给表单控件。
- 当您使用粗箭头功能时,分配给表单控件的是粗箭头定义本身。每次调用粗箭头函数时(在有效性检查期间),它都会重新评估
Validators.max(this.totalAmount)
并使用当前值 this.totalAmount
创建新的验证函数,从而使其成为动态的。
如果您使用反应形式,请执行以下操作:
将此添加到您的 formBuilder.group
offerPrice: [this.offer.offerPrice, [Validators.required, Validators.pattern('^\d+(\.\d{1,2})?$'), Validators.pattern('^[1-9]+[0-9]*$'),
(control: AbstractControl) => Validators.max(this.maxAmount)(control),
(control: AbstractControl) => Validators.min(this.minAmount)(control)]],
在您的 html 上,使用如下:
<div class=" form-group">
<mat-form-field>
<input class="form-control" matInput formControlName="offerPrice" placeholder="Gift Amount" [ngClass]="{'is-invalid': submitted && f.offerPrice.errors}" *ngIf="!useSlab"/>
<div *ngIf="submitted && f.offerPrice.errors">
<mat-error *ngIf="f.offerPrice.errors.required">This is required</mat-error>
<mat-error *ngIf="f.offerPrice.errors.min">Minimum offer price should be {{minAmount}}</mat-error>
<mat-error *ngIf="f.offerPrice.errors.max">Maximum offer price should be {{maxAmount}}</mat-error>
<mat-error *ngIf="f.offerPrice.errors.pattern">Price should be greater than zero</mat-error>
</div>
</mat-form-field>
</div>
只是对前面答案的一点补充,当你需要设置同一个表单的另一个formControl的一个formControl的验证器的值时,你可以在没有验证器的情况下初始化表单,然后注册它们,就像这个:
const form: FormGroup = this._fb.group({
from: [''],
to: ['']
});
form.controls.from.setValidators([
Validators.required,
(control: AbstractControl) => Validators.max(this.form.controls.to.value)(control)
]);
to
也是如此。
一个强大而清晰的解决方案是使用setValidators()
当您使用 setValidators() 时,代码更容易让其他人理解,并且当您要使用的动态值可能会根据用户在表单中的输入而改变时,此解决方案也适用。
例如,在你的组件中有这样的东西:
setInputValidation() {
this.totalAmount = this.countryOfOrigin?.value === 'US' ? 40 : 30;
this.value?.setValidators(Validators.max(this.totalAmount));
}
您可以根据此动态值在模板中显示自定义错误:
<mat-error *ngIf="value?.hasError('max')">
Must be less than {{ totalAmount }}.
</mat-error>
在我处理的案例中,我在表单中有一个下拉列表需要更改另一个输入的 max
验证。所以我使用了上面的代码,然后简单地将其添加到下拉列表的 mat-select
中:
<mat-select formControlName="countryOfOrigin"
(selectionChange)="setInputValidation()"
name="country">
<mat-option *ngFor="let country of countries" value="country">
{{ country }}
</mat-option>
</mat-select>
瞧,每次用户从下拉列表中做出选择时,输入的有效最大值都会发生变化,错误将根据新值显示。
注意:如果您的输入还有其他验证器,您在使用setValidators()
时必须添加它们。
我有一项服务,其中 returns 用户拥有的代表金钱的价值,我希望用户能够以等于或小于总金额的价值进行交易。我试过像这样使用最大验证:
valid() {
const form: FormGroup = this._fb.group({
fond: ['', [Validators.required]],
serie: ['', [Validators.required]],
account: ['', [Validators.required, Validators.min(1)]],
value: ['', [Validators.required, Validators.min(1)]],
subAccount: ['', [Validators.required, Validators.min(1)]]
});
return form;
}
但是不行,好像max()
中的值必须从一开始就设置,所以它会假定totalAmount为undefined。
更新您已编辑的问题:
使用这个:
value: ['', [
Validators.required,
Validators.min(1),
(control: AbstractControl) => Validators.max(this.totalAmount)(control)
]]
您可以使用以下语法实现:
(control: AbstractControl) => Validators.max(this.totalAmount)(control)
为什么?
- 当您提供
Validators.max(this.totalAmount)
时,它会使用给定参数(this.totalAmount
的当前值)创建一个验证函数,然后将其分配给表单控件。 - 当您使用粗箭头功能时,分配给表单控件的是粗箭头定义本身。每次调用粗箭头函数时(在有效性检查期间),它都会重新评估
Validators.max(this.totalAmount)
并使用当前值this.totalAmount
创建新的验证函数,从而使其成为动态的。
如果您使用反应形式,请执行以下操作:
将此添加到您的 formBuilder.group
offerPrice: [this.offer.offerPrice, [Validators.required, Validators.pattern('^\d+(\.\d{1,2})?$'), Validators.pattern('^[1-9]+[0-9]*$'),
(control: AbstractControl) => Validators.max(this.maxAmount)(control),
(control: AbstractControl) => Validators.min(this.minAmount)(control)]],
在您的 html 上,使用如下:
<div class=" form-group">
<mat-form-field>
<input class="form-control" matInput formControlName="offerPrice" placeholder="Gift Amount" [ngClass]="{'is-invalid': submitted && f.offerPrice.errors}" *ngIf="!useSlab"/>
<div *ngIf="submitted && f.offerPrice.errors">
<mat-error *ngIf="f.offerPrice.errors.required">This is required</mat-error>
<mat-error *ngIf="f.offerPrice.errors.min">Minimum offer price should be {{minAmount}}</mat-error>
<mat-error *ngIf="f.offerPrice.errors.max">Maximum offer price should be {{maxAmount}}</mat-error>
<mat-error *ngIf="f.offerPrice.errors.pattern">Price should be greater than zero</mat-error>
</div>
</mat-form-field>
</div>
只是对前面答案的一点补充,当你需要设置同一个表单的另一个formControl的一个formControl的验证器的值时,你可以在没有验证器的情况下初始化表单,然后注册它们,就像这个:
const form: FormGroup = this._fb.group({
from: [''],
to: ['']
});
form.controls.from.setValidators([
Validators.required,
(control: AbstractControl) => Validators.max(this.form.controls.to.value)(control)
]);
to
也是如此。
一个强大而清晰的解决方案是使用setValidators()
当您使用 setValidators() 时,代码更容易让其他人理解,并且当您要使用的动态值可能会根据用户在表单中的输入而改变时,此解决方案也适用。
例如,在你的组件中有这样的东西:
setInputValidation() {
this.totalAmount = this.countryOfOrigin?.value === 'US' ? 40 : 30;
this.value?.setValidators(Validators.max(this.totalAmount));
}
您可以根据此动态值在模板中显示自定义错误:
<mat-error *ngIf="value?.hasError('max')">
Must be less than {{ totalAmount }}.
</mat-error>
在我处理的案例中,我在表单中有一个下拉列表需要更改另一个输入的 max
验证。所以我使用了上面的代码,然后简单地将其添加到下拉列表的 mat-select
中:
<mat-select formControlName="countryOfOrigin"
(selectionChange)="setInputValidation()"
name="country">
<mat-option *ngFor="let country of countries" value="country">
{{ country }}
</mat-option>
</mat-select>
瞧,每次用户从下拉列表中做出选择时,输入的有效最大值都会发生变化,错误将根据新值显示。
注意:如果您的输入还有其他验证器,您在使用setValidators()
时必须添加它们。