📜  如何在 ngx bootstrap typeahead 中添加搜索记录列表 (1)

📅  最后修改于: 2023-12-03 15:38:21.793000             🧑  作者: Mango

如何在 Ngx Bootstrap Typeahead 中添加搜索记录列表

介绍

Ngx Bootstrap 是 Angular 的一个 UI 组件库,其中包含了 Typeahead 组件,可以实现输入框的自动补全功能。在 Typeahead 的默认行为中,用户输入字符时会在预设的数据源中查找匹配项,并在下拉框中展示匹配项列表。但有些时候我们需要在 Typeahead 中添加搜索记录列表,以便用户方便选择之前的搜索记录。

实现
数据保存

首先,我们需要在用户每次输入字符时,将用户输入的字符保存下来。这个可以通过 RxJS 的 Subject 对象来做到。在 Typeahead 组件中,有一个 onSelect 的事件,可以在用户选择一项匹配项时获取用户输入的字符。我们可以在这个事件中通过 Subject 对象来保存输入字符。

import { Component } from '@angular/core';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-typeahead',
  templateUrl: './typeahead.component.html',
  styleUrls: ['./typeahead.component.scss']
})
export class TypeaheadComponent {
  search$: Subject<string> = new Subject<string>();

  onSelect(event: any): void {
    this.search$.next(event.target.value);
  }
}
数据展示

接下来,我们需要将历史搜索记录展示在搜索结果的下拉框中。我们可以自定义一个模板来展示这些历史搜索记录。在这个模板中,我们可以使用 ngFor 指令来遍历历史搜索记录,并在搜索结果下拉框中展示出来。

<input type="text"
       [ngbTypeahead]="search"
       (selectItem)="onSelect($event)"
       [resultTemplate]="template"
       [inputFormatter]="formatter"
       class="form-control">

<ng-template #template let-result>
  <div class="search-item">
    {{ result }}
  </div>
</ng-template>
数据过滤

最后,我们需要在 Typeahead 中添加一个按钮,当用户点击这个按钮时,过滤出历史搜索记录中与当前输入字符匹配的项。

<input type="text"
       [ngbTypeahead]="search"
       (selectItem)="onSelect($event)"
       [resultTemplate]="template"
       [inputFormatter]="formatter"
       class="form-control">

<ng-template #template let-result>
  <div class="search-item">
    {{ result }}
  </div>
</ng-template>

<div class="search-history">
  <button class="btn btn-link" (click)="filterHistory()">
    Search History
  </button>
  <div *ngIf="historyOpened" class="search-history-list">
    <div *ngFor="let item of history | searchFilter: searchTerm" (click)="selectHistory(item)" class="search-item">
      {{ item }}
    </div>
  </div>
</div>
添加搜索记录过滤器

搜索记录过滤器可以根据当前输入字符 searchTerm,过滤出历史搜索记录中与 searchTerm 匹配的项。

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'searchFilter'
})
export class SearchFilterPipe implements PipeTransform {
  transform(items: any[], searchTerm: string): any[] {
    if (!items) {
      return [];
    }
    if (!searchTerm) {
      return items;
    }

    searchTerm = searchTerm.toLowerCase();
    return items.filter(item => item.toLowerCase().includes(searchTerm));
  }
}
完整代码
import { Component } from '@angular/core';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-typeahead',
  templateUrl: './typeahead.component.html',
  styleUrls: ['./typeahead.component.scss']
})
export class TypeaheadComponent {
  search$: Subject<string> = new Subject<string>();
  history: string[] = [
    'Apple',
    'Banana',
    'Cherry',
    'Date',
    'Elderberry',
    'Fig',
    'Grape',
    'Lemon',
    'Mango',
    'Orange',
    'Peach',
    'Pear',
    'Quince',
    'Raspberry',
    'Strawberry'
  ];
  historyOpened = false;
  searchTerm = '';

  onSelect(event: any): void {
    this.search$.next(event.target.value);
  }

  filterHistory(): void {
    this.historyOpened = true;
  }

  selectHistory(item: any): void {
    this.historyOpened = false;
    this.searchTerm = item;
  }

  formatter(result: string): string {
    return result;
  }
}

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'searchFilter'
})
export class SearchFilterPipe implements PipeTransform {
  transform(items: any[], searchTerm: string): any[] {
    if (!items) {
      return [];
    }
    if (!searchTerm) {
      return items;
    }

    searchTerm = searchTerm.toLowerCase();
    return items.filter(item => item.toLowerCase().includes(searchTerm));
  }
}

总结

以上就是在 Ngx Bootstrap Typeahead 中添加搜索记录列表的完整实现流程。通过自定义模板、使用搜索记录过滤器等,我们可以方便地给用户提供搜索历史记录,提高搜索体验。