我如何在<mat-select>组件中实现自动完成? 我想将自动完整功能与多选择垫式选择器相结合,因为选项列表将很长。 我已经在Stackoverflow上搜索了答案和CLO ...

问题描述 投票:0回答:3
谢谢你

Edit:我发现,Angular的PrimeFaces确实具有一个多选择列表,可让您搜索ListItems。它还包括一个内置的选择按钮!您可以在此处找到它

https://www.primefaces.org/primeng/#/multiselect

您可以使用npm install primeng --save

安装PrimeFaces

您可以使用

MatAutocomplete

和一些技巧来实现自动完整的多选择。我相当确定您不能使用

MatSelect

来做到这一点,因为这不能使您控制输入元素。该技术有些奇怪,但效果很好。这个想法是管理控制器中的选择,并将每个

mat-option的“值”设置为同一件事 - 您选择的选项。您还需要捕获点击以允许用户与列表进行交互(而不是在单击时立即关闭),并且当然在mat-option

项目中提供复选框。还有其他一些技巧也是必需的-here是一个快速而肮脏的例子

,显示该怎么做。

Html:

angular angular-material angular-material2
3个回答
29
投票
<mat-form-field class="example-full-width"> <input type="text" placeholder="Select Users" aria-label="Select Users" matInput [matAutocomplete]="auto" [formControl]="userControl"> <mat-hint>Enter text to find users by name</mat-hint> </mat-form-field> <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn"> <mat-option *ngFor="let user of filteredUsers | async" [value]="selectedUsers"> <div (click)="optionClicked($event, user)"> <mat-checkbox [checked]="user.selected" (change)="toggleSelection(user)" (click)="$event.stopPropagation()"> {{ user.firstname }} {{ user.lastname }} </mat-checkbox> </div> </mat-option> </mat-autocomplete> <br><br> <label>Selected Users:</label> <mat-list dense> <mat-list-item *ngIf="selectedUsers?.length === 0">(None)</mat-list-item> <mat-list-item *ngFor="let user of selectedUsers"> {{ user.firstname }} {{ user.lastname }} </mat-list-item> </mat-list>

TS:


import { Component, OnInit, ViewChild } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

export class User {
  constructor(public firstname: string, public lastname: string, public selected?: boolean) {
    if (selected === undefined) selected = false;
  }
}

/**
 * @title Multi-select autocomplete
 */
@Component({
  selector: 'multiselect-autocomplete-example',
  templateUrl: 'multiselect-autocomplete-example.html',
  styleUrls: ['multiselect-autocomplete-example.css']
})
export class MultiselectAutocompleteExample implements OnInit {

  userControl = new FormControl();

  users = [
    new User('Misha', 'Arnold'),
    new User('Felix', 'Godines'),
    new User('Odessa', 'Thorton'),
    new User('Julianne', 'Gills'),
    new User('Virgil', 'Hommel'),
    new User('Justa', 'Betts'),
    new User('Keely', 'Millington'),
    new User('Blanca', 'Winzer'),
    new User('Alejandrina', 'Pallas'),
    new User('Rosy', 'Tippins'),
    new User('Winona', 'Kerrick'),
    new User('Reynaldo', 'Orchard'),
    new User('Shawn', 'Counce'),
    new User('Shemeka', 'Wittner'),
    new User('Sheila', 'Sak'),
    new User('Zola', 'Rodas'),
    new User('Dena', 'Heilman'),
    new User('Concepcion', 'Pickrell'),
    new User('Marylynn', 'Berthiaume'),
    new User('Howard', 'Lipton'),
    new User('Maxine', 'Amon'),
    new User('Iliana', 'Steck'),
    new User('Laverna', 'Cessna'),
    new User('Brittany', 'Rosch'),
    new User('Esteban', 'Ohlinger'),
    new User('Myron', 'Cotner'),
    new User('Geri', 'Donner'),
    new User('Minna', 'Ryckman'),
    new User('Yi', 'Grieco'),
    new User('Lloyd', 'Sneed'),
    new User('Marquis', 'Willmon'),
    new User('Lupita', 'Mattern'),
    new User('Fernande', 'Shirk'),
    new User('Eloise', 'Mccaffrey'),
    new User('Abram', 'Hatter'),
    new User('Karisa', 'Milera'),
    new User('Bailey', 'Eno'),
    new User('Juliane', 'Sinclair'),
    new User('Giselle', 'Labuda'),
    new User('Chelsie', 'Hy'),
    new User('Catina', 'Wohlers'),
    new User('Edris', 'Liberto'),
    new User('Harry', 'Dossett'),
    new User('Yasmin', 'Bohl'),
    new User('Cheyenne', 'Ostlund'),
    new User('Joannie', 'Greenley'),
    new User('Sherril', 'Colin'),
    new User('Mariann', 'Frasca'),
    new User('Sena', 'Henningsen'),
    new User('Cami', 'Ringo')
  ];

  selectedUsers: User[] = new Array<User>();

  filteredUsers: Observable<User[]>;
  lastFilter: string = '';

  ngOnInit() {
    this.filteredUsers = this.userControl.valueChanges.pipe(
      startWith<string | User[]>(''),
      map(value => typeof value === 'string' ? value : this.lastFilter),
      map(filter => this.filter(filter))
    );
  }

  filter(filter: string): User[] {
    this.lastFilter = filter;
    if (filter) {
      return this.users.filter(option => {
        return option.firstname.toLowerCase().indexOf(filter.toLowerCase()) >= 0
          || option.lastname.toLowerCase().indexOf(filter.toLowerCase()) >= 0;
      })
    } else {
      return this.users.slice();
    }
  }

  displayFn(value: User[] | string): string | undefined {
    let displayValue: string;
    if (Array.isArray(value)) {
      value.forEach((user, index) => {
        if (index === 0) {
          displayValue = user.firstname + ' ' + user.lastname;
        } else {
          displayValue += ', ' + user.firstname + ' ' + user.lastname;
        }
      });
    } else {
      displayValue = value;
    }
    return displayValue;
  }

  optionClicked(event: Event, user: User) {
    event.stopPropagation();
    this.toggleSelection(user);
  }

  toggleSelection(user: User) {
    user.selected = !user.selected;
    if (user.selected) {
      this.selectedUsers.push(user);
    } else {
      const i = this.selectedUsers.findIndex(value => value.firstname === user.firstname && value.lastname === user.lastname);
      this.selectedUsers.splice(i, 1);
    }

    this.userControl.setValue(this.selectedUsers);
  }

}

一种方法是在MAT-SELECT中添加手动过滤器,以便它具有自动完整功能。
找到下面给定解决方案的示例代码Herey

添加过滤文本的输入控制器 public filterControl = new FormControl();

添加垫子内部的滤波器文本字段

<mat-select [id]="fieldId" [formControl]="custonDropdown" (selectionChange)="onSelectChange($event.value)" (closed)="onPanelClose()" multiple panelClass="custom-mat-select"> <input matInput [formControl]="filterControl" type="text" name="filter-options" id="filter-options" placeholder="Search"> <mat-option *ngFor="let option of filteredOptions | async" [value]="option.value" [ngClass]="{'hide': !option.show}"> {{option.name | translate}} </mat-option> </mat-select> 现在添加一个事件侦听器,用于过滤文本字段值更改

     this.filteredOptions = this.filterControl.valueChanges.pipe(
            startWith(''),
            map((value: string) => {
                this.optionItems
                    .forEach(option => {
                        option.show = option.name.toLocaleLowerCase().includes(value.toLowerCase());
                    });
                return this.optionItems;
            })
        );

10
投票
(closed)="onPanelClose()"

onPanelClose() { this.filterControl.setValue(''); }

demo


是的,您可以使用Primeng MultiSelect控件。唯一的问题是,如果您担心主题。

使用

mat-select-autocomplet
是另一个选项

如何安装:


npm install select-autocomplete --save

NPM:

Https://www.npmjs.com/package/mat-select-autocomplete


demo:https://stackblitz.com/edit/mat-select-autocomplete


1
投票

角v8.x

显示选项下拉(单击/激活选择控件)时,您可以开始键入(必须非常快😅)以使第一个匹配选项突出显示。然后只需按Enter(或左键按钮单击)选择突出显示的选项🔥 要使它更加放松🐌将此属性更改为您的欲望:

@Input({ transform: numberAttribute }) typeaheadDebounceInterval: number Minor下降:

基于

startsWith(“中间的文本”上没有匹配) no匹配选项的幻想过滤

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.