如何在Angular中为选择框(select)添加搜索过滤器

16

我试图在我的选择选项列表中添加搜索过滤器,因为有许多选项,没有搜索的话,用户很难找到他想要选择的选项。

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

这是我的代码(只是我的表格的一部分)

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

1
你是否在寻找 https://www.npmjs.com/package/angular-ng-autocomplete? - jitender
1
使用Angular Material的自动完成组件:https://material.angular.io/components/autocomplete/overview - Rik de Vos
是的,我想使用Angular Material的自动完成功能,但我不知道怎么做!我会尝试。 - PowerGirl
5个回答

12
如果您想在选择选项中进行过滤,则可以使用HTML的datalist控件。如果使用它,则无需进行额外的过滤编程,因为它已经内置了过滤功能。
HTML:
<input list="menace" name="menace">

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

输入值怎么样? - PowerGirl
所选选项将显示在输入字段中。您可以将输入与所选值绑定。 - Parth Dhankecha
<input list="menace" name="menace"> <datalist id="menace" (change)="mnVuln?.menaceActif?.menace.id = $event.target.value; updateMenaceProcessus()"> <option *ngFor="let menace of menaces" [selected]="menace.id === mnVuln?.menaceActif?.menace.id">{{menace.nom}} </option> </datalist> 这是我尝试做的,但它不起作用。 - PowerGirl
1
要绑定数据列表,请按照stackoverflow的此链接进行操作bind datalist and get object - Parth Dhankecha
我认为这是一个正确的答案,但界面非常简单,很难修改以便在除了宠物项目之外的实际用途上使用。 - Pepe Alvarez

5

2
谢谢!我会看一下的。 - PowerGirl
1
太完美了!非常感谢。 - umunBeing

2
如果您想通过键入第一个字母来过滤数组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>

TypeScript:

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:

如果您想按值过滤:

HTML:

input是指输入框的标签。
<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>

TypeScript:

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


@PowerGirl,你能具体说一下哪里出了问题吗?我已经测试过了,它是可以工作的。 - StepUp
问题在这里:@ViewChild('selectList') selectList: ElementRef;!@ViewChild必须有两个参数。 - PowerGirl
@PowerGirl 我已经更新了我的答案。请查看我的更新答案。此外,我还创建了一个示例 https://stackblitz.com/edit/angular-qjf89w - StepUp
@PowerGirl 我很高兴能帮助你! - StepUp

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

这个很好用,如果是表单的情况下,只需添加一个表单控件名称,就可以获取到值。由@ParthDhankecha回答。


0

我无法找到任何简单的方法来实现这个选择器,但自动完成组件似乎非常接近所需的功能。唯一的问题是,它不需要所选值是选项之一。因此,我创建了以下指令:

// 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将会很有帮助。

干杯🍻


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接