Пользовательская Удаленная Проверка Угловой Реактивной Формы

#c# #angular #api #.net-core

Вопрос:

Я использую веб-API .NET Core и Angular. И я пытаюсь реализовать пользовательскую проверку, чтобы проверить, является ли заголовок уникальным или нет.

Я пользуюсь службой проверки

  uniqueTitleValidator() : ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => { 
  if(control.value === "") {
    return  null;
  }
this.albumService.uniqueTitleValidate(control.value).subscribe((data:boolean)=>this.isExist = data);
return  this.isExist ? { titleAlreadyExists: {value: control.value}} : null;   
};
 

Вот компонент формы

 ngOnInit(): void {
this.albumForm  = this.formBuilder.group({
  id: [Guid.EMPTY],
  title: ['', {
    validators: [
      Validators.required,
      Validators.maxLength(15),
      Validators.pattern("^[a-zA-Z0-9' '-'_s]*"),
      this.titleValidator.uniqueTitleValidator()
    ],
    updateOn: 'change'
  },
  ],
  description: ['']
});
if(this.formData){
  this.albumForm.patchValue(this.formData)
}
 

И html-шаблон

 <form [formGroup] = "albumForm" formnovalidate>
<div class="form-group">
    <label for="title">Title</label>
    <input id="title" type="text" formControlName="title" class="form-control" required/>
    <div *ngIf="title.invalid amp;amp; (title.dirty || title.touched)"
    class="error">
       <div *ngIf="title.errors?.required">
        Title is required. 
        </div>
        <div *ngIf="title.errors.maxlength">
            Title should be under 15 characters.
        </div>
        <div *ngIf="title.errors?.pattern">
            Only A-Z, a-z, 0-9, ' ', '-', '_' characters are allowed.
        </div>
        <div *ngIf="title.errors?.titleAlreadyExists">
           Album already exists.
        </div>
</div>      
</div>
<div class="form-group">
    <label for="description">Description</label>
    <input id="id" type="text" class="form-control" hidden/>
    <input id="description" type="text" class="form-control" />
</div>
<div class="form-group">
    <input type="button" (click)="onClick($event)" value="Save" [disabled]="!albumForm.valid" class="btn btn-success" />
    <a routerLink="/manage/albums" class="btn btn-danger ml-2">Cancel</a>
</div>
 

И контроллер

  [HttpGet]
    [Route("api/albums/validation")]
    public async Task<IActionResult> CheckTitle(string title)
    {
            var album = await _albumService.GetAlbumByTitleAsync(title);
            if (album != null)
                return Ok(true);
            return Ok(false);
    }
 

Но у меня есть проблема. Например: У меня есть альбом в базе данных с названием «Альбом 1».
Когда я ввожу недопустимый «Альбом 1» в форму, он показывает, что форма действительна. Затем я ввожу действительные данные, например «Альбом 2», которого нет в базе данных, он показывает ошибку. Это похоже на обновление формы до изменения значения или что-то в этом роде.

Ответ №1:

Попробуйте это:

 uniqueTitleValidator() : ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => { 
  if(control.value === "") {
    return  null;
  }
this.albumService.uniqueTitleValidate(control.value)
.subscribe((data:boolean)=> {
   if (data) { 
      return {titleAlreadyExists: {value: control.value}}
   } else {
      return null
   }
});

};
 

Но я думаю, что лучшей практикой было бы использовать асинхронный валидатор:

Комментарии:

1. Большое спасибо! Реализация асинхронного валидатора решила мою проблему. Теперь это работает правильно.

2. Пожалуйста. Мне очень приятно это слышать!