Angular 自定义验证器在其中使用订阅时不会抛出错误
Angular custom validator is not throwing an error when using subscribe in it
我正在尝试创建自定义验证器,它需要命中两个端点以获取所需的数据,然后比较数据的属性,如果它们不相等,那么我想抛出一个错误。这是验证器。
checkIfSalaIsFull(control: AbstractControl): {[salaIsFull: string] : boolean}{
if(control.value !=null){
this.salaService.findActiveCards(control.value).subscribe(karty=>{
this.salaService.findSalaByNRSali(control.value).subscribe(sala =>{
if(karty.length === sala.pojemnosc){
console.log(karty.length);
console.log(sala.pojemnosc);
return {'salaIsFull' : true};
}
});
});
}
return null;
}
问题是即使 console.log 显示的属性值相同,也不会抛出错误。
<div class="form-group">
<label for="nr_sali">Numer sali</label>
<select class="form-control" id="nr_sali" formControlName="nr_sali">
<option *ngFor="let sala of sale" [value]="sala.nr_sali" >{{sala.nr_sali}} - {{sala.oddzial}}</option>
</select>
<span *ngIf="formAddKarta.get('nr_sali').errors?.salaIsFull"
class="help-block text-danger">
Sala jest pełna
</span>
</div>
我的后端工作正常,我和邮递员核实过。
这也是我正在使用的 FormGroup 的设置:
this.formAddKarta = new FormGroup({
data_przyjecia: new FormControl(null, [KartyListaComponent.checkIfDateIsLessThanToday.bind(this),
Validators.required]),
godzina_przyjecia: new FormControl(null,[Validators.required]),
data_wypisu: new FormControl(null),
nr_sali: new FormControl(null, [Validators.required,this.checkIfSalaIsFull.bind(this)]),
pesel: new FormControl(this.pesel)
});
我在 nr_sali FormControl 的验证器 table 中设置了这个自定义验证器。
编辑:
我尝试使用 map 而不是 subscribe,但它没有发送检索 sala 的请求,只发送检索 karty 的请求。
checkIfSalaIsFull(control: AbstractControl): {[salaIsFull: string] : boolean}{
if(control.value !=null){
this.salaService.findActiveCards(control.value).subscribe(karty=>{
this.salaService.findSalaByNRSali(control.value).pipe(map(sala =>{
if(karty.length === sala.pojemnosc){
console.log(karty.length);
console.log(sala.pojemnosc);
return {'salaIsFull' : true};
}else{
return null;
}
}));
});
}else{
return null;
}
}
继续我上面的评论,您想使用地图而不是订阅。自 Angular 6 起,rxjs(库映射来自)包装要求将其操作包装在管道函数中,如下所示:
import { map } from 'rxjs/operations'
...
this.salaService.findSalaByNRSali(control.value).pipe(map(sala => {
// Do work
// ...
}));
- 你需要使用异步验证器而不是验证器,因为你需要发送请求,并且你需要将你的函数作为第三个参数放在你的 formControl 中(作为异步验证器)
- 你的验证器函数应该是 return
Observable<ValidationErrors | null> | Promise<ValidationErrors | null>
- 您需要使用
switchMap and map
而不是订阅
这里是代码示例
进口
import { map, switchMap } from "rxjs/operators";
import { Observable } from "rxjs/internal/observable";
异步验证器示例
checkIfSalaIsFull(
control: AbstractControl
): Observable<ValidationErrors | null> {
if (control.value != null) {
return this.salaService.findActiveCards(control.value).pipe(
switchMap(karty => {
return this.salaService.findSalaByNRSali(control.value).pipe(
map(sala => {
console.log(karty.length);
console.log(sala.pojemnosc);
return karty.length === sala.pojemnosc ? { salaIsFull: true } : null;
})
);
})
);
}
return null;
}
表单实现示例
this.formAddKarta = new FormGroup({
data_przyjecia: new FormControl(null, [
KartyListaComponent.checkIfDateIsLessThanToday.bind(this), /** <-- if this function send the request you need to change this one too */
Validators.required]),
godzina_przyjecia: new FormControl(null, [Validators.required] ),
data_wypisu: new FormControl(null),
nr_sali: new FormControl(null,
[Validators.required],
[this.checkIfSalaIsFull.bind(this)]), /** <-- third argument of formControl is the async validators array */
pesel: new FormControl(this.pesel)
});
我正在尝试创建自定义验证器,它需要命中两个端点以获取所需的数据,然后比较数据的属性,如果它们不相等,那么我想抛出一个错误。这是验证器。
checkIfSalaIsFull(control: AbstractControl): {[salaIsFull: string] : boolean}{
if(control.value !=null){
this.salaService.findActiveCards(control.value).subscribe(karty=>{
this.salaService.findSalaByNRSali(control.value).subscribe(sala =>{
if(karty.length === sala.pojemnosc){
console.log(karty.length);
console.log(sala.pojemnosc);
return {'salaIsFull' : true};
}
});
});
}
return null;
}
问题是即使 console.log 显示的属性值相同,也不会抛出错误。
<div class="form-group">
<label for="nr_sali">Numer sali</label>
<select class="form-control" id="nr_sali" formControlName="nr_sali">
<option *ngFor="let sala of sale" [value]="sala.nr_sali" >{{sala.nr_sali}} - {{sala.oddzial}}</option>
</select>
<span *ngIf="formAddKarta.get('nr_sali').errors?.salaIsFull"
class="help-block text-danger">
Sala jest pełna
</span>
</div>
我的后端工作正常,我和邮递员核实过。
这也是我正在使用的 FormGroup 的设置:
this.formAddKarta = new FormGroup({
data_przyjecia: new FormControl(null, [KartyListaComponent.checkIfDateIsLessThanToday.bind(this),
Validators.required]),
godzina_przyjecia: new FormControl(null,[Validators.required]),
data_wypisu: new FormControl(null),
nr_sali: new FormControl(null, [Validators.required,this.checkIfSalaIsFull.bind(this)]),
pesel: new FormControl(this.pesel)
});
我在 nr_sali FormControl 的验证器 table 中设置了这个自定义验证器。
编辑:
我尝试使用 map 而不是 subscribe,但它没有发送检索 sala 的请求,只发送检索 karty 的请求。
checkIfSalaIsFull(control: AbstractControl): {[salaIsFull: string] : boolean}{
if(control.value !=null){
this.salaService.findActiveCards(control.value).subscribe(karty=>{
this.salaService.findSalaByNRSali(control.value).pipe(map(sala =>{
if(karty.length === sala.pojemnosc){
console.log(karty.length);
console.log(sala.pojemnosc);
return {'salaIsFull' : true};
}else{
return null;
}
}));
});
}else{
return null;
}
}
继续我上面的评论,您想使用地图而不是订阅。自 Angular 6 起,rxjs(库映射来自)包装要求将其操作包装在管道函数中,如下所示:
import { map } from 'rxjs/operations'
...
this.salaService.findSalaByNRSali(control.value).pipe(map(sala => {
// Do work
// ...
}));
- 你需要使用异步验证器而不是验证器,因为你需要发送请求,并且你需要将你的函数作为第三个参数放在你的 formControl 中(作为异步验证器)
- 你的验证器函数应该是 return
Observable<ValidationErrors | null> | Promise<ValidationErrors | null>
- 您需要使用
switchMap and map
而不是订阅
这里是代码示例
进口
import { map, switchMap } from "rxjs/operators";
import { Observable } from "rxjs/internal/observable";
异步验证器示例
checkIfSalaIsFull(
control: AbstractControl
): Observable<ValidationErrors | null> {
if (control.value != null) {
return this.salaService.findActiveCards(control.value).pipe(
switchMap(karty => {
return this.salaService.findSalaByNRSali(control.value).pipe(
map(sala => {
console.log(karty.length);
console.log(sala.pojemnosc);
return karty.length === sala.pojemnosc ? { salaIsFull: true } : null;
})
);
})
);
}
return null;
}
表单实现示例
this.formAddKarta = new FormGroup({
data_przyjecia: new FormControl(null, [
KartyListaComponent.checkIfDateIsLessThanToday.bind(this), /** <-- if this function send the request you need to change this one too */
Validators.required]),
godzina_przyjecia: new FormControl(null, [Validators.required] ),
data_wypisu: new FormControl(null),
nr_sali: new FormControl(null,
[Validators.required],
[this.checkIfSalaIsFull.bind(this)]), /** <-- third argument of formControl is the async validators array */
pesel: new FormControl(this.pesel)
});