自动完成需要时间来第一次呈现

autocomplete taking time to render for first time

我有一个输入字段,我正在通过 bing api.

搜索位置
this.addressForm
  .get('queryField')
  .valueChanges.debounceTime(100)
  .distinctUntilChanged()
  .switchMap(query => this.onChangeSearch(query))
  .subscribe(res => {
    console.log(res);
  });

注:

当我们加载应用程序时,第一次 当我在字段中只输入 1 个字符 时,它需要几秒钟渲染视图。 API 响应很好,但列表会在几秒钟后填充。

从第二次开始不会出现这种情况。

更改检测 - 这是分支:https://stackblitz.com/edit/angular-ng-autocomplete-7ryhdv?file=src%2Fapp%2Fapp.component.ts

这些是行:

  constructor(
    private bingApiLoader: BingApiLoaderService,
    private fg: FormBuilder,
    private ref: ChangeDetectorRef <- ADD THIS
  ) {}

...

    this.manager.getSuggestions(search, res => {
      this.countries = res.map(r => {
        return {
          formattedSuggestion: r.formattedSuggestion,
          address: r.address
        };
      });
      this.results = this.countries;
      this.ref.detectChanges(); <- AND THIS
    });

实际上,您应该对所有内容(而不是实例成员)使用可观察对象,并且您的模板应该只订阅它们。

这是我的意思的一个例子。 https://stackblitz.com/edit/angular-ivy-k47m7k

它使用了我很久以前写的一个包(忽略包本身),但只需要注意没有实例成员,模板所做的就是使用 async pipe 订阅可观察对象。

我见过很多非常有经验的 angular 开发人员完全按照 OP 在 有状态组件 * 上所做的工作 - 只需创建一些实例成员,调用 detectChanges() 当他们觉得必须这样做时。但实际上,当您处理有状态组件时,您的模板应该只是订阅可观察对象。

*有状态组件是创建了某种数据并将传递给子组件的组件。