【问题标题】:angular 5 material 2 - auto complete getting data from external apiangular 5 material 2 - 自动完成从外部 api 获取数据
【发布时间】:2020-11-21 13:35:43
【问题描述】:

我正在使用角度 5 和材质 2。

在 ts 文件中,我有这个属性:

      filteredOptions: Observable<any[]>;

此属性将有一组值显示在自动完成字段中。

      [{
        id:'1', name: 'teste 1'},
        {id:'2', name: 'teste 2'},
        {id:'3', name: 'teste 3'
      }]

这个值数组来自数据库,它会在用户输入之后显示出来。

html 文件:

          ##            <form class="example-form">
          ##              <mat-form-field class="example-full-width">
          ##                <input type="text" placeholder="Assignee" aria-label="Assignee" matInput [formControl]="myControl" [matAutocomplete]="auto">
          ##                <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
          ##                  <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
          ##                    {{ option.name }}
          ##                  </mat-option>
          ##                </mat-autocomplete>
          ##              </mat-form-field>
          ##            </form>

ts 文件示例:

    this.filteredOptions = Observable<any[]>;

    ngOnInit() {
      this.filteredOptions = this.myControl.valueChanges
        .pipe(
          startWith({}),
          map(getArrayOfValue(val))            
        );
      }

      // it is going to call an api to get the array of values to be shown in the field
      getArrayOfValue(val): Observable<any[]> {            
        const url = this.ROOT_URL + 'veiculo/' + val;
        return this.http.get<any[]>(url);
      }

这段代码给我一个错误

src/app/oficina/cadastro/veiculo/veiculo.component.ts(55,5) 中的错误: 错误 TS2322:类型 'Observable>' 不可分配 输入“可观察”。类型“可观察”不是 可分配给类型“任何[]”。 “Observable”类型中缺少属性“includes”

【问题讨论】:

  • 您的传入数据是什么样的?请将 JSON 响应复制粘贴到您的问题。您正在谈论获取一个对象,但您在问题中显示的是一个数组?
  • 感谢您的回答。我换个问题。我不确定我是否足够清楚,但我想要的是使用来自数据库而不是来自页面中的对象的数据加载自动完成。

标签: angular rest angular-material2


【解决方案1】:

我看到了一些问题,例如你应该map(val =&gt; this.getArrayOfValue(val))。但我也建议进行一些额外的更改。考虑添加debounceTimedistinctUntilChangedswitchMap。设置您选择的去抖时间。这并不是为了完全重载 api。以及 switchMap 对于使请求切换到用户输入的最后一个值很有用。此外,您应该考虑为您的 api 请求使用服务,这通常是我们处理事情的方式。所以我建议将 http-request 移动到服务并从组件中调用它。

TS:

  // inject your created service which makes the http-request
  constructor(private service: Service) { 

  this.filteredOptions = this.myControl.valueChanges
        .pipe(
          startWith(''),
          debounceTime(400),
          distinctUntilChanged(),
          switchMap(val => {
            return this.filter(val || '')
          })       
        );
  }

  // filter and return the values
 filter(val: string): Observable<any[]> {
    // call the service which makes the http-request
    return this.service.getData()
     .pipe(
       map(response => response.filter(option => { 
         return option.name.toLowerCase().indexOf(val.toLowerCase()) === 0
       }))
     )
   }  
}

然后服务会调用 http-request。如果您不重载 API,我们可以在第一次获取后将数据存储在变量中,然后返回该变量的 observable,但这只是可选的。

opts = [];

getData() {
  return this.opts.length ?
    of(this.opts) :
    this.http.get<any>('https://jsonplaceholder.typicode.com/users').pipe(tap(data => this.opts = data))
}

您似乎在模板中使用value 作为您的选项。如果要捕获整个对象,请使用[value]

这里有一个 DEMO 供你玩 :)

【讨论】:

  • ERROR TypeError: response.filter 不是一个函数,我使用的是heremap geolocation api
  • 我正在尝试在服务中实现这一点,但不确定调用 ts 组件文件中的内容以及与搜索词一起移动到服务的内容。
猜你喜欢
  • 1970-01-01
  • 2018-10-19
  • 2018-04-02
  • 1970-01-01
  • 2020-01-11
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 2017-07-29
相关资源
最近更新 更多