搜索栏通过API自动完成

时间:2019-12-13 06:49:26

标签: angular angular-material

我正在尝试创建一个具有自动完成功能的图书搜索栏,该栏将在每次按键时动态显示相关结果。一切正常,我正在获取数据,但结果未显示在下拉菜单上

使用角度8和材料8.2.3

我正在尝试创建一个具有自动完成功能的图书搜索栏,该栏将在每次按键时动态显示相关结果。一切正常,我正在获取数据,但结果未显示在下拉菜单上

    import { Component, OnInit } from '@angular/core';
    import { Store } from '@ngrx/store';
    import { AppState } from '../app.state/app.state';
    import { Observable } from 'rxjs/Observable';
    import { UserName } from '../../model/name.model';
    import { FormControl, FormGroup, FormBuilder } from '@angular/forms';
    import { MainService } from '../main.service';
    
    @Component({
      selector: 'app-search',
      templateUrl: './search.component.html',
      styleUrls: ['./search.component.css']
    })
    export class SearchComponent implements OnInit {
      searchForm: FormGroup;
    
      username: Observable<UserName[]>;
      searchTerm: string;
      searchResult: [];
      isLoading = false;
      errorMsg: string;
    
      constructor(private store: Store<AppState>, private searchService: MainService, private formBuilder: FormBuilder) {
        this.username = store.select('username');
       }
    
      ngOnInit() {
        this.searchForm = this.formBuilder.group({
          searchBar: ''
        });
        this.onChanges();
      }
    
      onChanges(): void {
        this.searchForm.get('searchBar').valueChanges.subscribe(val => {
          this.searchService.searchingValue(val).subscribe(function(data){
            this.searchResult = data.items;
          } );
    
        });
    
      }
     
      }

    <!-- <p>{{ username.username }}</p> -->
    <h1>Book Search</h1>
    <form [formGroup]="searchForm">
        
            <!-- <mat-form-field>
                 <input type="text" matInput formControlName="searchBar" [matAutocomplete]="auto">
            </mat-form-field> -->
    
                <mat-form-field>
                    <input matInput placeholder="Search" aria-label="State" [matAutocomplete]="auto"  formControlName="searchBar">
                    <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
                      <mat-option *ngIf="isLoading" class="is-loading">Loading...</mat-option>
                      <ng-container *ngIf="!isLoading">
                        <mat-option *ngFor="let option of searchResult" [value]="option">
                          <span>{{ option.volumeInfo.title }}</span>
    
                        </mat-option>
                      </ng-container>
                    </mat-autocomplete>
                  </mat-form-field>
              
            
    </form>

2 个答案:

答案 0 :(得分:0)

您可以将创建的可观察对象直接传递给自动完成控件:

ts

...
    searchResult: Observable;

          onChanges(): void {
                this.searchResult = this.searchForm.get('searchBar').valueChanges.pipe(
                 switchMap(val => this.searchService.searchingValue(val))    
                );

              }
...

html

<h1>Book Search</h1>
<form [formGroup]="searchForm">

        <!-- <mat-form-field>
             <input type="text" matInput formControlName="searchBar" [matAutocomplete]="auto">
        </mat-form-field> -->

            <mat-form-field>
                <input matInput placeholder="Search" aria-label="State" [matAutocomplete]="auto"  formControlName="searchBar">
                <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
                  <mat-option *ngIf="isLoading" class="is-loading">Loading...</mat-option>
                  <ng-container *ngIf="!isLoading">
                    <mat-option *ngFor="let option of searchResult | async" [value]="option">
                      <span>{{ option.volumeInfo.title }}</span>

                    </mat-option>
                  </ng-container>
                </mat-autocomplete>
              </mat-form-field>


</form>

答案 1 :(得分:0)

总工作量示例,您可以在此StackBlitz Link

中找到此处

onChange()方法,您必须首先通过管道()传递所有rxjs运算符,例如filter,debounceTime和switchMap。在此处,当文本输入更改时,您可以先检查valueChanges,然后在switchMap()中触发服务api调用数据。

onChanges(){
   this.searchForm.get('searchBar').valueChanges.pipe(
      filter( data => data.trim().length > 0 ),
      debounceTime(500),
      switchMap(  (id: string) => {
         return id ? this.serachService.searchingValue(id.replace(/[\s]/g,'')) : of([]);
      })
   ).subscribe(data =>{
      this.searchResult = data as Array<{}>; 
   })
}

此处

  • 第一个pipe()运算符是 filter(),用于过滤用户输入的所有黑色空格。因此,没有什么要求api请求。
  • 第二个pipe()运算符是 debounceTime(500),用于等待停止用户键入。并且恰好在5ms搜索字符串在switchMap()的api请求上传递后
  • 第三个pipe()运算符是 switchMap(),用于在每次valueChanges之后切换到新的可观察对象。

search.service.ts

searchingValue(value){
    return of(this.bookDetails.filter( booksName => booksName.name.replace(/[\s]/g,'').toLowerCase().indexOf(value.toLowerCase()) === 0 ));
}