Angular material Chips Autocomplete

Chips Autocomplete 官网的例子我没法正常使用,无法实现搜索

我的select是个通用组件,现在贴代码:

component.ts

javascript 复制代码
import {
  Component,
  ElementRef,
  forwardRef,
  Input,
  OnChanges,
  OnDestroy,
  OnInit,
  SimpleChanges,
  ViewChild,
} from '@angular/core';
import { Tag } from '../../models/tag/tag';
import { map, startWith, takeUntil } from 'rxjs/operators';
import { ControlValueAccessor, UntypedFormControl, NG_VALUE_ACCESSOR } from '@angular/forms';
import { COMMA, ENTER } from '@angular/cdk/keycodes';
import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
// import { MatChipInputEvent } from '@angular/material/chips';
import { TagService } from '../../services/tag/tag.service';
import { TagType } from '../../enums/TagType';
import { ISearchOptions } from '../../interfaces/SearchOptions';
import { SubscriberWrapperComponent } from '../subscriber-wrapper/subscriber-wrapper.component';

@Component({
  selector: 'app-tags-select',
  templateUrl: './tags-select.component.html',
  styleUrls: ['./tags-select.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => TagsSelectComponent),
      multi: true,
    },
  ],
})
export class TagsSelectComponent
  extends SubscriberWrapperComponent
  implements ControlValueAccessor, OnChanges, OnInit, OnDestroy
{
  @Input() title: string;
  @Input() disabled: boolean;
  @Input() color: 'primary' | 'accent' | 'warn';
  @Input() type: TagType;
  @Input() tags: Tag[];

  filteredTags: Tag[];
  selectedTags: Tag[] = [];
  separatorKeysCodes: number[] = [ENTER, COMMA];
  tagCtrl = new UntypedFormControl('');
  hideComponent: boolean;

  @ViewChild('tagInput') tagInput: ElementRef<HTMLInputElement>;
  @ViewChild('chipList') chipList: ElementRef;

  constructor(private tagService: TagService) {
    super();
  }

  onChange = (_: any) => {};
  onTouched = () => {};

  async ngOnInit() {
    this.initTags();
    const conditions = [];
    if (this.type) {
      conditions.push({
        key: 'type',
        value: this.type,
        operator: '=',
      });
    }
    this.tags = await this.listTags('', {
      conditions,
    });
    await this.updateFilterTags();
  }

  async listTags(query: string = '', options: ISearchOptions = {}) {
    if (!this.tags) {
      const response = await this.tagService.list(query, options);
      return response.entities;
    } else {
      return this.tags;
    }
  }

  // add(event: MatChipInputEvent): void {
  //   event.chipInput!.clear();

  //   this.tagCtrl.setValue(null);
  // }

  remove(tag: Tag): void {
    const index = this.selectedTags.indexOf(tag);
    if (index >= 0) {
      this.selectedTags.splice(index, 1);
    }
    this.filteredTags.push(tag);
    // this.onChange(this.selectedTags);  
  }

  selected(event: MatAutocompleteSelectedEvent): void {
    this.selectedTags.push(event.option.value);
    this.tagInput.nativeElement.value = '';
    this.tagCtrl.setValue(null);
    // this.onChange(this.selectedTags);
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  writeValue(selectedTags: Tag[] = []): void {
    this.selectedTags = selectedTags ?? [];
    this.updateFilterTags();
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.disabled?.currentValue) {
      this.tagCtrl.disable();
    }

    if (changes.tags?.currentValue) {
      this.updateFilterTags();
    }
  }

  initTags() {
    this.tagCtrl.valueChanges
      .pipe(
        takeUntil(this.unsubscribeAll),
        startWith(null),
        map(async (value?: string) => {
          await this.updateFilterTags(value);
        })
      )
      .subscribe();
  }

  async updateFilterTags(value?: string) {
    const conditions = [];
    if (this.type) {
      conditions.push({
        key: 'type',
        value: this.type,
        operator: '=',
      });
    }
    const response = value
    ? this.tags?.filter((tag: Tag) => {
        const regex = new RegExp(`^${value}`, 'i'); 
        return regex.test(tag.title?tag.title:'');
      }) || []
    : this.tags?.slice() || [];
    
    const selectedTagIds = this.selectedTags.map((tag: Tag) => tag.id);
    this.filteredTags = response.filter((tag: Tag) => !selectedTagIds.includes(tag.id));
  }
}

页面.html

html 复制代码
<mat-label>{{title}}</mat-label>
<mat-form-field class="tag-chip-list" *ngIf="!hideComponent">
  <mat-chip-list #chipList aria-label="Tag selection" [disabled]="disabled">
    <mat-chip [color]="color" [class]="color"
              *ngFor="let tag of selectedTags; let i=index"
              (removed)="remove(tag)">
      <button matChipRemove>
        <mat-icon svgIcon="CloseBlue" class="close-icon"></mat-icon>
      </button>
      {{tag.name}}
    </mat-chip>
    <input
      placeholder="Add another tag..."
      #tagInput
      [formControl]="tagCtrl"
      [matAutocomplete]="auto"
      [matChipInputFor]="chipList"
      [matChipInputSeparatorKeyCodes]="separatorKeysCodes">
  </mat-chip-list>
  <mat-autocomplete #auto="matAutocomplete"
                    (optionSelected)="selected($event)">
    <mat-option *ngFor="let tag of filteredTags" [value]="tag"
                [innerHTML]="tag.name">

    </mat-option>
  </mat-autocomplete>
</mat-form-field>
相关推荐
阿伟来咯~27 分钟前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端32 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱35 分钟前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai44 分钟前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨1 小时前
在JS中, 0 == [0] 吗
开发语言·javascript
bysking2 小时前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
王哲晓2 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
fg_4112 小时前
无网络安装ionic和运行
前端·npm
理想不理想v2 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云2 小时前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js