如何将搜索过滤器添加到 angular 中的 select 选项

How to add a search filter to a select option in angular

我正在尝试在我的 select 选项列表中添加搜索过滤器,因为有很多选项,我认为如果没有搜索,用户将不容易找到该选项他想要 select.

希望你能理解我,因为我的英语不好。

这是我的代码(它只是我 table 的一部分)

<ng-container *ngFor="let menaceProcessus of menaceProcessusTab">
    <tr>
         <td colspan="4" bgcolor="#f1f1f1"><b>{{menaceProcessus?.processus?.nom}}</b></td>
    </tr>
    <ng-container *ngFor="let actif of menaceProcessus?.actifs">
        <tr>
            <td [rowSpan]="actif?.menaces?.length+1">{{actif?.actif?.nom}}</td>
        </tr>
     <ng-container *ngFor="let mnVuln of actif?.menaces">
        <tr>
             <td>{{mnVuln?.vulnerabilite?.nom}}</td>
             <td>
                 <select class="form-control" 
                  (change)="mnVuln?.menaceActif?.menace.id = $event.target.value; 
                            updateMenaceProcessus()">
                      <option></option>
                      <option *ngFor="let menace of menaces" 
                          [value]="menace.id" 
                          [selected]="menace.id === mnVuln?.menaceActif?.menace.id">
                        {{menace.nom}}</option>
                  </select>
              </td>
              <td>
                 <input class="form-control" 
                    type="text" [value]="mnVuln?.menaceActif?.probabilite"> 
              </td>
          </tr>
      </ng-container>
    </ng-container>
 </ng-container>

如果您想通过输入第一个字母来过滤数组 menaces,则可以像这样过滤数组:

HTML:

<select class="form-control" 
     (change)="mnVuln?.menaceActif?.menace.id = $event.target.value; 
               updateMenaceProcessus();
               filterMenaces($event)">
    <option></option>
    <option *ngFor="let menace of menaces" 
        [value]="menace.id" 
        [selected]="menace.id === mnVuln?.menaceActif?.menace.id">
        {{menace.nom}}</option>
</select>

打字稿:

origMenaces = [];

methodAPIToGetMenaces() {
   this.yourService()
       .subscribe(s=> {
           this.menaces = s;
           this.origMenaces = s;
       });
}

filterMenaces(str: string) {
    if (typeof str === 'string') {
        this.menaces = this.origMenaces.filter(a => a.toLowerCase()
                                             .startsWith(str.toLowerCase())); 
    }
}

更新 1:

如果要按 input 值过滤:

HTML:

<input type="text"         
    (ngModelChange)="filterItem($event)" 
    [(ngModel)]="filterText">
    <br>
<select 
     #selectList
     [(ngModel)]="myDropDown" 
    (ngModelChange)="onChangeofOptions($event)">
    <option value="empty"></option>
    <option *ngFor="let item of items">         
        {{item}}
    </option>    
</select>
<p>items {{ items | json }}</p>

打字稿:

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 4';
  myDropDown : string;
  items = ['one', 'two', 'three'];
  origItems = ['one', 'two', 'three'];
  @ViewChild('selectList', { static: false }) selectList: ElementRef;

  onChangeofOptions(newGov) {
     console.log(newGov);
  }

  filterItem(event){
      if(!event){
          this.items = this.origItems;
      } // when nothing has typed*/   
      if (typeof event === 'string') {
          console.log(event);
          this.items = this.origItems.filter(a => a.toLowerCase()
                                             .startsWith(event.toLowerCase())); 
      }
      console.log(this.items.length);
      this.selectList.nativeElement.size = this.items.length + 1 ;       
   }      
}

Please, see work example at stackblitz

如果要在select选项中过滤,可以使用HTML的datalist控件。如果你使用它,就不需要为过滤做额外的编码。它具有用于过滤的内置功能。

HTML :

<input list="menace" name="menace">

<datalist id="menace">
     <option *ngFor="let menace of menaces">{{menace.nom}} </option>
</datalist>

我想你可以使用 ng-select: https://www.npmjs.com/package/@ng-select/ng-select 满足您的要求

我找不到为 select 执行此操作的任何简单方法,但是自动完成 组件似乎做了一些非常接近所需的事情。唯一的问题是,它不需要值是选项之一。这就是我创建以下指令的原因:

// mat-autocomplete-force-select.directive.ts
import { Directive, Input } from '@angular/core';
import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator } from '@angular/forms';
import { MatAutocomplete } from '@angular/material/autocomplete';

@Directive({
  selector: '[matAutocomplete][appMatAutocompleteForceSelect]',
  providers: [
    {
      provide: NG_VALIDATORS,
      useExisting: MatAutocompleteForceSelectDirective,
      multi: true,
    }
  ]
})
export class MatAutocompleteForceSelectDirective implements Validator {
  @Input('matAutocomplete')
  matAutocomplete!: MatAutocomplete;

  validate(control: AbstractControl): ValidationErrors | null {
    if (this.matAutocomplete.options && !this.isOptionOfAutocomplete(control.value)) {
      return { 'notAnAutocompleteValue' : true }
    }

    return null;
  }

  private isOptionOfAutocomplete(value: string) {
    return this.matAutocomplete.options.find(option => option.value === value) !== undefined;
  }
}

之后,你可以将指令添加到自动完成的输入中,如果不是那个,它会出现notAnAutocompleteValue的错误。

<input matInput type="text" appMatAutocompleteForceSelect [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" >
  <!-- ... -->
</mat-autocomplete>

对于不熟悉自动完成组件的任何人,https://material.angular.io/components/autocomplete/overview 将会有所帮助。

干杯:)

<input list="menace" name="menace">
<datalist id="menace">
 <option *ngFor="let menace of menaces">{{menace.nom}} </option>
</datalist>

这很好用,在表单的情况下,只需添加一个表单控件名称,就可以选择值。 @ParthDhankecha 回答