Асинхронная проверка угловых реактивных форм с использованием наблюдаемого из сервиса - PullRequest
1 голос
/ 01 октября 2019

Я делаю веб-приложение на Angular 8.3.4. У меня есть форма, использующая Reactive Forms, и я хочу добавить Async Validation, чтобы убедиться, что введенное имя уникально. Я прочитал множество примеров, но по какой-то причине у меня не работает.

Сервис

export class BrandService {
  brands: Observable<BrandId[]>;
}

Компонент

export class CreateNewComponent {

  form: FormGroup;

  constructor(
    private formBuilder: FormBuilder,
    private brandService: BrandService
  ) {
    // Creates a form group
    this.form = this.formBuilder.group({
      name: ['', Validators.compose([
        Validators.required,
        Validators.minLength(6),
        CustomValidator.unique(this.brandService.brands)
      ])]
    });
  }
}

Пользовательский валидатор

export class CustomValidator {

  static unique(brands: Observable<BrandId[]>) {
    return (control: AbstractControl) => {

      const name = control.value.toLowerCase();

      return brands.pipe(
        map(items => items.filter(b => b.name.toLowerCase() === name)),
        map(items => items.length ? {unique: false} : null)
      );

    };
  }

}

Я передаю Observable службы из компонента в CustomValidator. Прямо сейчас, элемент управления имеет: status: "INVALID"

Кстати, что я должен явно возвращать в моем методе unique?

Моя цель - узнать, существует ли имя вмассив Observable для возврата контрольной ошибки.

1 Ответ

0 голосов
/ 01 октября 2019

Асинхронный валидатор должен быть передан через другой массив (или сам по себе), что-то вроде

name: [
  '', 
  Validators.compose([ Validators.required, Validators.minLength(6)]), 
  () => CustomValidator.unique(this.brandService.brands)
]

Также обратите внимание, что он находится в функции, многие из примеров, которые я нашел ранее, использовали bind как в этой статье , но вместо этого мне нравится использовать функцию.

------ Редактировать ------ Вот рабочий пример

@Component({
  selector: 'app-new',
  templateUrl: './new.component.html',
  styleUrls: ['./new.component.css']
})
export class NewComponent {

  form: FormGroup;

  constructor(
    private formBuilder: FormBuilder,
    private brandService: BrandService,
  ) {
    const brand = new BrandId();
    brand.name = 'abcdef';

    this.brandService.brands = of([brand]);
    // Creates a form group
    this.form = this.formBuilder.group({
      name: ['', Validators.compose([
        Validators.required,
        Validators.minLength(6),
      ]),
        (control) => CustomValidator.unique(this.brandService.brands, control)]
    });
  }
}

export class CustomValidator {
  static unique(brands: Observable<BrandId[]>, control: AbstractControl) {
    const name = control.value.toLowerCase();

    return brands.pipe(
      map(items => items.filter(b => b.name.toLowerCase() === name)),
      map(items => items.length ? { unique: false } : null)
    );

  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...