0

我正在一个项目中使用 Angular Material Autocomplete 来获取可能非常大(数千行)的站点列表。

我知道这startWith会触发 100% 的记录(未过滤)的初始加载,我希望在startWith找到更好的方法后将其删除。

问题是:这个表单有很多过滤器,除非使用过滤器,否则我不想下载数据。所以我不希望所有字段都立即开始使用 API。我想等待下载数据(无论是否过滤),直到用户真正关注或触摸/单击输入。用角度做这件事的正确方法是什么?我一直在触发nativeElement.focus,但我有点卡住了。有什么建议吗?谢谢!

this.sites$ = this.filterGroup.get('site').valueChanges
  .pipe(
    startWith(''),
    debounceTime(400),
    switchMap(val => {
      return this.getSites(val)
    })
4

2 回答 2

1

您可以引入一个主题来触发您的抓取:

private fetchSites$ = new Subject<void>();

public sites$ = this.fetchSites$.pipe(
  startWith([]),
  switchMap(() => filterGroup.get('site').valueChanges),
  debounceTime(400),
  switchMap(val => this.getSites(val))
);

public fetchSites() {
  this.fetchSites$.next();
}

然后,在您的模板中,您可以触发fetchSites$.next()on(focus)事件:

    <input 
      [formControl]="myControl"
      [matAutocomplete]="auto"
      (focus)="fetchSites()"
    >

    <mat-autocomplete #auto>
      <mat-option *ngFor="let option of sites$ | async" [value]="option">
        {{option}}
      </mat-option>
    </mat-autocomplete>
于 2021-07-30T18:26:35.203 回答
0

我做了这样的事情来跟踪元素何时“模糊”,这意味着它失去了焦点:

  @ViewChildren(FormControlName, { read: ElementRef }) formInputElements: ElementRef[];

  ngAfterViewInit(): void {
    // Watch for the blur event from any input element on the form.
    // This is required because the valueChanges does not provide notification on blur
    const controlBlurs: Observable<any>[] = this.formInputElements
      .map((formControl: ElementRef) => fromEvent(formControl.nativeElement, 'blur'));

    // Merge the blur event observable with the valueChanges observable
    // so we only need to subscribe once.
    merge(this.productForm.valueChanges, ...controlBlurs).pipe(
      debounceTime(800)
    ).subscribe(value => {
      this.displayMessage = this.genericValidator.processMessages(this.productForm);
    });
  }

这是你要问的吗?

于 2021-07-29T23:12:17.777 回答