Angular 5 - Bootstrap typeahead - вызов, наблюдаемый при каждом изменении формы - PullRequest
0 голосов
/ 12 июня 2018

У меня есть форма с выбором и начальной загрузкой в ​​моем компоненте.

<form #clanForm="ngForm" (change)="formChange(clanForm.value)(ngSubmit)="onSubmit(clanForm.value)">
  <div class="row">
    <div class="col-sm-4">
      <label class="col-form-label" for="locationSelector"><b>Location</b></label>
    </div>
    <div class="col-sm-8" *ngIf="locations">
      <select class="custom-select" id="locationSelector" name="location" [(ngModel)]="filterModel.selectedLocationId">
        <option *ngFor="let location of locations" [value]="location.id">{{location.name}}</option>
      </select>
    </div>
  </div>
    <div class="container row">
      <div class="col-sm-9">
        <input type="text" [(ngModel)]="filterModel.selectedClanNameOrClanTag" typeaheadOptionField="tag"
               class="form-control" [typeaheadOptionsInScrollableView]="4"
               placeholder="Enter clan id or name..." minlength="3" [typeaheadScrollable]="true" [typeaheadAsync]="true"
               name="clanNameOrClanTag" required [typeahead]="dataSource"
              (keyup)="formChange(clanForm.value)(ngModelChange)="formChange(clanForm.value)">
      </div>
      <div class="col-sm-3">
        <button type="submit" class="btn btn-primary mb-2" [disabled]="!clanForm.form.valid">Search</button>
      </div>
    </div>
</form>

Теперь нужно позвонить и сделать http-запрос каждый раз, когда происходит изменение формы.Либо выбирается что-то в select, либо происходит изменение ввода.Пока что мой компонент выглядит так:

@Component({
  selector: 'app-clan-search',
  templateUrl: './clan-search.component.html',
  styleUrls: ['./clan-search.component.css']
})
export class ClanSearchComponent implements OnInit {

  public locations: LocationsType[] = [];

  public dataSource: Observable<ClansByClantagType[]>;
  public searchResult: ClansByClantagType[] = [];
  public filterModel: FilterModel = new FilterModel();
  public formChanges: EventEmitter<FilterModel> = new EventEmitter<FilterModel>();

  constructor(private router: Router, 
              private clanSearchService: ClanSearchService,
              private locationService: LocationSearchService) {
  }

  ngOnInit() {
    this.locationService.getLocations().subscribe(locations => this.locations = locations);
    this.dataSource = Observable.create((observer: any) => this.formChanges.debounceTime(300)
      .subscribe(() => this.getClan(observer))).switchMap(() => {
      return Observable.of(this.searchResult);
    });
  }

  private getClan(observer: any) {   
    this.clanSearchService.getClanByClanTag(this.filterModel).subscribe(
        (result: ClansByClantagType) => {
          this.searchResult = [];
          this.searchResult.push(result);
          observer.next(result);
        });
  }

  onSubmit(value) {
    this.router.navigate(['clanSearch/' + value.clanNameOrClanTag]);
  }

  formChange(value) {
    this.formChanges.emit(value);
  }
}

Наверное, я неправильно реализовал formchanges.subscribe() У вас есть идеи?

1 Ответ

0 голосов
/ 12 июня 2018

Для такого рода задач реактивная форма больше подходит.Вы должны слушать form.valueChanges.Все, что вам нужно, это что-то вроде ниже:

 this.dataSource = this.form.valueChanges.pipe(
     debounceTime(300),
     switchMap(value => this.clanSearchService.getClanByClanTag(value))
 );

Пожалуйста, прочитайте о реактивных формах здесь .Вам, вероятно, также понадобится использовать асинхронный канал, а вот документы асинхронного канала

...