Angular材质从API自动完成

时间:2019-09-09 10:59:14

标签: angular autocomplete material

我尝试使用api的自动完成功能,但无法正常工作。 它只能在没有api的情况下工作。

这是我的组件TS:里面,有一个来自api(onGetTaxList)数据的回调方法

import { Component, OnInit } from '@angular/core';
import { UsersService } from '../../../../core/services/users.service';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

@Component({
  selector: 'app-create-process-modal',
  templateUrl: './create-process-modal.component.html',
  styleUrls: ['./create-process-modal.component.sass']
})
export class CreateProcessComponent implements OnInit {
  myControl = new FormControl();
  options = [
    { name: 'One' },
    { name: 'Two' },
    { name: 'Tree' },
  ];
  filteredOptions: Observable<any>;


  constructor(private service: UsersService) { }

  ngOnInit() {
    this.service.createNewProcess((data) => this.onGetTaxList(data));
    this.filteredOptions = this.myControl.valueChanges
      .pipe(
        startWith(''),
        map(value => this._filter(value))
      );
  }

  onGetTaxList(data) {
    console.log(data);
  }
  private _filter(value: string) {
    const filterValue = value.toLowerCase();

    return this.options.filter(option => option.name.toLowerCase().includes(filterValue));
  }
}

组件html:

<div class="formContainer">
    <h2 style="text-align: right">New Process</h2>
    <mat-form-field style="text-align: right">
        <input type="text" placeholder="Start Typing..." matInput [formControl]="myControl" [matAutocomplete]="auto">
        <mat-autocomplete #auto="matAutocomplete">
                <mat-option *ngFor="let option of filteredOptions | async" [value]="option.name">
                  {{option.name}}
                </mat-option>
              </mat-autocomplete>
    </mat-form-field>

</div>

在这种状态下,它与对象一起工作

options = [
        { name: 'One' },
        { name: 'Two' },
        { name: 'Tree' },
      ];

现在我需要数据API的工作:

0: {companyName: "ziro", cid: "524023240", partners: Array(4)}
1: {companyName: "plus", cid: "524023240", partners: Array(2)}

,我需要自动完成过滤器companyName。 谢谢。

5 个答案:

答案 0 :(得分:2)

从呼叫数据中取出所有数据的最佳方式,但服务器端的部分数据: 电话从第一个字母开始

组件无异步

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

.ts 文件

ngOnInit() {
    this.myControl.valueChanges
      .subscribe(value => {
        if(value.length >= 1){
          this.dashboardService.getProductsByName(value).subscribe(response => {
            this.filteredOptions = response;
          });
        }
        else {
          return null;
        }
      })
}

答案 1 :(得分:0)

在您的ngOnInit上尝试添加以下内容:

ngOnInit() {
   .
   ..
   ...
   this.options = []; //init the options data.
   this.yourService.getAllCompaniesOrSomething.subscribe((all_companies)=>{
      this.options = all_companies.map((company)=>{ 
                          return {
                                    name:company.companyName
                          } 
                      });//closing the map function.
   });//closing the subscription.
}

答案 2 :(得分:0)

已解决:

    import { Component, OnInit } from '@angular/core';
    import { UsersService } from '../../../../core/services/users.service';
    import { FormControl } from '@angular/forms';
    import { Observable } from 'rxjs';
    import { map, startWith } from 'rxjs/operators';
    import { MatAutocompleteSelectedEvent } from '@angular/material';

    @Component({
      selector: 'app-create-process-modal',
      templateUrl: './create-process-modal.component.html',
      styleUrls: ['./create-process-modal.component.sass']
    })
    export class CreateProcessComponent implements OnInit {
      myControl = new FormControl();
      options;
      filteredOptions: Observable<any>;


      constructor(private service: UsersService) { }

      ngOnInit() {
        this.service.createNewProcess((data) => this.onGetTaxList(data));
      }

      // Auth Complete
      onGetTaxList(data) {
        this.options = data;
        this.filteredOptions = this.myControl.valueChanges
          .pipe(
            startWith(''),
            map(value => value.length >= 1 ? this._filter(value) : [])
          );
      }
      private _filter(value: string) {
        const filterValue = value.toLowerCase();

        return this.options.filter(option => option.companyName.toLowerCase().includes(filterValue));
      }
}

HTML:

<div class="formContainer">
    <h2 style="text-align: right">New Process</h2>
    <mat-form-field style="text-align: right">
        <input type="text" placeholder="Start Typing..." matInput [formControl]="myControl" [matAutocomplete]="auto">
        <mat-autocomplete #auto="matAutocomplete">
                <mat-option *ngFor="let option of filteredOptions | async" [value]="option.companyName">
                  {{option.companyName}}
                </mat-option>
              </mat-autocomplete>
    </mat-form-field>

</div>

答案 3 :(得分:0)

我认为甚至没有尝试从Api获取数据,因此首先您应该添加它。然后,您尝试用数据中不存在的name进行过滤,您想用companyName进行过滤,然后使用它。总之,将您的代码更改为:

this.filteredOptions = this.myControl.valueChanges
  .pipe(
    startWith(''),
    switchMap(value => this._filter(value))
  );

以及用于过滤并从api获取数据的函数:

private _filter(value: string) {
  const filterValue = value.toLowerCase();
  // add your service function here
  return this.service.getData().pipe(
    filter(data => !!data),
    map((data) => {
      return data.filter(option => option.companyName.toLowerCase().includes(value))
    })
  )
}

演示: StackBlitz

答案 4 :(得分:0)

组件:

  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
       }))
     )
   }  
}

服务:

opts = [];

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

要查看完整的演示,请检查此链接Stackblitz