简体   繁体   English

将API中的JSON数据实现为mat-autocomplete输入

[英]Implement JSON data from API into mat-autocomplete input

I am trying to use Angular Material Component "Highlight the first autocomplete option" onto an input which uses JSON data from an API server (which already works by fetching all the JSON data). 我正在尝试使用Angular Material组件“突出显示第一个自动完成选项”到使用来自API服务器的JSON数据的输入上(通过获取所有JSON数据已经可以正常工作)。 Don't know where I am going wrong with this. 不知道我要怎么做。

I have tried using the Angular Material example but that uses the hardcoding method where I need my data from an API 我尝试使用Angular Material示例,但是在需要从API获取数据的地方使用了硬编码方法

service.ts 服务

import { Appl } from '../intdets';
export class IntdetsService {
  private url = "/assets/IntDet.json";
  constructor(private http: HttpClient) { }

  getName(): Observable<Appl[]> {
    return this.http.get<Appl[]>(this.url);
  }
}


intdets.ts

export class Appl {
    _NAME: string;
}

JSON

{
  "_APPLS": [
    {
     "_NAME": "some string",
    },...]}

component.ts

export class IntdetsComponent implements OnInit {
  public apps = [];
  testCtrl: FormControl;
  filteredTest: Observable<Appl[]>;

  constructor(private _intdetsService: IntdetsService) { 
this.testCtrl = new FormControl();
    this.filteredTest = this.testCtrl.valueChanges
      .pipe(
            startWith(null),
            switchMap(val => { return this.filterTest(val || '' )}));
  }
  filterTest(val: string) {
    return this._intdetsService.getName().pipe(
      map(res => res.filter(s => {
        return s._NAME.toLowerCase().indexOf(val.toLowerCase()) === 0
      }))
    ) 
  }
  ngOnInit() {
    this._intdetsService.getName()
        .subscribe(data => {
          this.apps = data;
          console.log(data);
         });
  }
}

HTML
         <mat-form-field >
            <mat-label>Test Name</mat-label>
            <input type="text" matInput [formControl]="testCtrl" [matAutocomplete]="autoTest">
            <mat-autocomplete autoActiveFirstOption #autoTest="matAutocomplete">
               <mat-option *ngFor="let test of filteredTest | async" [value]="test._APPLS">
               {{test._NAME}}
               </mat-option>
            </mat-autocomplete>
         </mat-form-field>
      </p>

The array you want, is inside _APPLS , so you need to extract that: 所需的数组位于_APPLS ,因此您需要提取该数组:

getName(): Observable<Appl[]> {
  return this.http.get<any>(this.url).pipe(
    map(data => data._APPL as Appl[])
  )
}

I would also suggest, that in the service you would store the response in a variable after first fetch. 我还建议,在服务中,您应在首次获取后将响应存储在变量中。 We wouldn't want to overload an api by fetching data on each keystroke. 我们不想通过在每个按键上获取数据来使api重载。 You could do like: 您可以这样做:

data = <Appl[]>[];

getName(): Observable<Appl[]> {
 return this.data.length 
   ? of(this.data) 
   : this.http.get<any>(this.url).pipe(
       map(data => { 
         this.data = data._APPL as Appl[]
         return this.data;
       })
     )
}

You could also consider adding a debounceTime on your form control change. 您也可以考虑在表单控件更改中添加debounceTime

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM