角度5材料2 - 自动完成从外部api获取数据

时间:2017-12-04 16:09:06

标签: angular rest angular-material2

我使用角度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:键入&#39; Observable&gt;&#39;不可分配   键入&#39; Observable&#39;。输入&#39; Observable&#39;不是   可分配给&#39;任何[]&#39;。       财产包括&#39;类型&#39; Observable&#39;

中缺少

1 个答案:

答案 0 :(得分:17)

我看到了一些问题,例如你应该map(val => this.getArrayOfValue(val))。但我还建议一些额外的改变。考虑添加debounceTimedistinctUntilChangedswitchMap。设置您选择的去抖时间。这,不要完全超载api。以及switchMap有助于将请求切换到用户键入的最后一个值。您还应考虑为api请求使用服务,这通常是我们处理事务的方式。所以我建议将http请求移到服务中并从组件中调用它。

TS:

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

  this.filteredOptions = this.myControl.valueChanges
        .pipe(
          startWith(null),
          debounceTime(200),
          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
       }))
     )
   }  
}

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

这是一个 DEMO 供您玩:)