几天来,我一直在try 修复一些Angular 15代码,但我找不到解决方案. 我使用的是带有NGX-MAT-SELECT-Search和虚拟滚动cdk-Virtual-scroll-viewport的MAT-SELECT(传统). 当我 Select 一个值时,它会显示,但当我搜索某个值时,它不会显示,但它是可读的,我可以在我的控制台中显示它,但不能在我的MAT-SELECT中显示.

我在this stackblitz link面临着同样的问题,你可以搜索"Bank C"并 Select 它,但当你搜索"Bank Q"并 Select 它时,值不会显示.

以下是我的html代码:

<mat-form-field>
<mat-select [formControl]="formControl"
            [placeholder]="placeholder"
            [(ngModel)]="values"
            [matTooltip]="getTooltip(values)"
            [multiple]="multiple"
            [required]="required"
            (openedChange)="openChange($event)">

    <mat-option *ngIf="!hideSearch">
        <ngx-mat-select-search
            [placeholderLabel]="filterItem"
            [noEntriesFoundLabel]="noItemMatch"
            [formControl]="filterItemCtrl"
            [showToggleAllCheckbox]="showAllCheckbox"
            [toggleAllCheckboxChecked]="showAllCheckbox && multiple && items.length && values.length === items.length"
            (toggleAll)="checkAllItems($event)">
        </ngx-mat-select-search>
    </mat-option>

    <mat-option *ngIf="emptyItem">{{ emptyItem }}</mat-option>

    <cdk-virtual-scroll-viewport [itemSize]="5" [style.height.px]=viewPortHeightPx class="custom-viewport">
        <mat-option *cdkVirtualFor="let item of filteredItems | async;" 
                    [value]="item"
                    (onSelectionChange)="clickOption($event)">
            <div >
                {{ item }}
            </div>
         </mat-option>
    </cdk-virtual-scroll-viewport>
</mat-select>

谢谢你帮我.

推荐答案

这真的很难调试,但基本上问题是,当mat-option在虚拟卷轴的渲染窗口之外时,该选项将不会被选中,所以我编写了一个特殊的切片方法,它将始终将选定的库放置在数组的顶部,因此肯定会被选中,这解决了您的问题.

  getCorrectSlice(): Bank[] {
    const output = this.banks.slice();
    const bank: Bank = this.bankCtrl.value;
    if (bank) {
      return [bank, ...this.banks];
    }
    return this.banks.slice();
  }

上面的代码创建了在开始处具有所选值的切片!

HTML

<h3>Single selection</h3>
<p>
  <mat-form-field>
    <mat-select
      id="bank"
      id="bank"
      [formControl]="bankCtrl"
      placeholder="Bank"
      #singleSelect
      [compareWith]="compareWith"
      (selectionChange)="selectionChange($event)"
    >
      <mat-option>
        <ngx-mat-select-search
          [formControl]="bankFilterCtrl"
        ></ngx-mat-select-search>
      </mat-option>

      <!-- <mat-option *ngFor="let bank of filteredBanks | async" [value]="bank">
        {{bank.name}}
      </mat-option> -->
      <cdk-virtual-scroll-viewport [itemSize]="42" [style.height.px]="4 * 42">
        <mat-option [value]="{ name: 'any', id: -1 }">Any</mat-option>
        <mat-option
          *cdkVirtualFor="let bank of filteredBanks | async; trackBy: trackBy"
          [value]="bank"
          >{{ bank.name }}</mat-option
        >
      </cdk-virtual-scroll-viewport>
    </mat-select>
  </mat-form-field>
</p>
<p>Selected Bank: {{ bankCtrl.value?.name }}</p>

TS

import {
  AfterViewInit,
  Component,
  OnDestroy,
  OnInit,
  ViewChild,
} from '@angular/core';
import { FormControl } from '@angular/forms';
import { MatSelect } from '@angular/material/select';
import { ReplaySubject, Subject } from 'rxjs';
import { take, takeUntil } from 'rxjs/operators';

import { Bank, BANKS } from '../demo-data';

@Component({
  selector: 'app-single-selection-example',
  templateUrl: './single-selection-example.component.HTML',
  styleUrls: ['./single-selection-example.component.scss'],
})
export class SingleSelectionExampleComponent
  implemenTS OnInit, AfterViewInit, OnDestroy
{
  /** list of banks */
  protected banks: Bank[] = BANKS;

  /** control for the selected bank */
  public bankCtrl: FormControl = new FormControl();

  /** control for the MatSelect filter keyword */
  public bankFilterCtrl: FormControl = new FormControl();

  /** list of banks filtered by search keyword */
  public filteredBanks: ReplaySubject<Bank[]> = new ReplaySubject<Bank[]>(1);

  @ViewChild('singleSelect', { static: true }) singleSelect: MatSelect;

  /** Subject that emiTS when the component has been destroyed. */
  protected _onDestroy = new Subject<void>();

  constructor() {}

  ngOnInit() {
    // set initial selection

    // load the initial bank list
    this.bankCtrl.setValue(this.banks[10]);
    this.filteredBanks.next(this.getCorrectSlice());

    // listen for search field value changes
    this.bankFilterCtrl.valueChanges
      .pipe(takeUntil(this._onDestroy))
      .subscribe(() => {
        this.filterBanks();
      });
  }

  ngAfterViewInit() {}

  ngOnDestroy() {
    this._onDestroy.next();
    this._onDestroy.complete();
  }

  getCorrectSlice(): Bank[] {
    const output = this.banks.slice();
    const bank: Bank = this.bankCtrl.value;
    if (bank) {
      return [bank, ...this.banks];
    }
    return this.banks.slice();
  }

  compareWith(a: Bank, b: Bank) {
    return a && a.name && b && b.name ? a === b : false;
  }

  protected filterBanks() {
    let search = this.bankFilterCtrl.value;
    if (!this.banks || !search) {
      return;
    }
    // get the search keyword
    if (!search) {
      this.filteredBanks.next(this.getCorrectSlice());
      return;
    } else {
      search = search.toLowerCase();
    }
    // filter the banks
    this.filteredBanks.next(
      this.banks.filter((bank) => bank.name.toLowerCase().indexOf(search) > -1)
    );
  }

  selectionChange(e: any) {
    this.bankFilterCtrl.setValue('');
    this.filteredBanks.next(this.getCorrectSlice());
  }

  trackBy(index: number, item: Bank) {
    return item.id;
  }
}

stackblitz

Angular相关问答推荐

Angular 形式验证:在空和不匹配的密码上显示错误

Angular 17上的material 工具提示的自定义样式

未触发HTTP拦截器

如何在ANGLING v17中使用鞋带样式组件?

PathMatch full始终连接到参数化路径,即使完整路径不匹配也是如此

天使17中的倒计时器

元素上的Angular 管道链接不起作用

ngx-http-client 在 Angular 16 中已弃用

Angular *ngIf 表达式中这么多冒号的作用是什么?

Angular p-triStateCheckbox for each Select 更改不同的 colored颜色

Chart.js 如何编辑标题标签 colored颜色

在一个组件中创建多个表单

全局异常处理

在 Ionic 2 中使用图像资源的正确方法

Angular CLI 自定义 webpack 配置

样式 html,来自 Web 组件的正文

在 Angular rxjs 中,我什么时候应该使用 `pipe` 与 `map`

formGroup 需要一个 FormGroup 实例

输入更改时Angular2动态输入字段失go 焦点

NPM 脚本 start退出,但未指示 Angular CLI 正在侦听请求