简体   繁体   English

Angular mat-chips with mat-autocomplete and input组合,从列表中选择时增加一个额外的芯片

[英]Angular mat-chips with mat-autocomplete and input combined, adds an extra chip when selecting from list

I have combined mat-chips autocomplete and input (as both are present in the example section in the docs), but it creates a problem, when I type in part of an Autocomplete Option to filter the options, and then click it, it adds the input value plus the clicked item to the chip list.我已经结合了 mat-chips 自动完成和输入(因为两者都出现在文档的示例部分中),但是当我输入部分自动完成选项来过滤选项时,它会产生一个问题,然后单击它,它会添加输入值加上点击的项目到芯片列表。 which is probably a very logcial thing for it to do, since i dont see any reason why it should ignore the blur event if the item was clicked, is there a built-in way / hack to work around this?这对它来说可能是一件非常合乎逻辑的事情,因为我看不出有任何理由为什么它应该在单击项目时忽略模糊事件,是否有内置的方法/破解来解决这个问题? here is my code:这是我的代码:

<mat-form-field class="chip-list">
    <mat-chip-list #chipList aria-label="Op selection" class="mat-chip-list-stacked">
        <mat-basic-chip *ngFor="let sop of selectedOps" [selectable]="selectable" 
         [removable]="removable" (removed)="remove(sop)">
            <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
            {{sop.val}}
        </mat-basic-chip>
    </mat-chip-list>
    <div style="position: relative;">
        <input matInput [formControl]="chipControl" aria-label="subcats" #SelectInput
            [matAutocomplete]="auto" [matChipInputFor]="chipList" 
           [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
            (matChipInputTokenEnd)="add($event)" [matChipInputAddOnBlur]="addOnBlur">
       
        <mat-icon class="icon" (click)="SelectInput.focus()">keyboard_arrow_down</mat-icon>
    </div>

    <mat-autocomplete #auto="matAutocomplete">
        <mat-option *ngFor="let op of filteredOps | async" [value]="op">

            <div (click)="optionClicked($event, op)">
                <mat-checkbox [checked]="op.selected" (change)="toggleSelection(op)"
                    (click)="$event.stopPropagation(); ">
                    {{ op.val }}
                </mat-checkbox>
            </div>

        </mat-option>

    </mat-autocomplete>
</mat-form-field>

was I doing something wrong?我做错了什么吗? or is it not ment to work together in the first place?还是一开始就不应该一起工作? thanks for any feedback!感谢您的任何反馈!

Here's a solution as posted @ https://github.com/angular/components/issues/19279#issuecomment-627263513这是@ https://github.com/angular/components/issues/19279#issuecomment-627263513发布的解决方案

Quote from there:从那里引用:

We can emulate matChipInputAddOnBlur self.我们可以模拟 matChipInputAddOnBlur 自己。

I added (blur)=addOnBlur($event) to the input and disabled matChipInputAddOnBlur.我在输入中添加了 (blur)=addOnBlur($event) 并禁用了 matChipInputAddOnBlur。 Click on mat-input should be ignored.点击 mat-input 应该被忽略。

my implementation:我的实现:

 addOnBlur(event: FocusEvent) {
    const target: HTMLElement = event.relatedTarget as HTMLElement;
    if (!target || target.tagName !== 'MAT-OPTION') {
      const matChipEvent: MatChipInputEvent = {input: this.fruitInput.nativeElement, value : this.fruitInput.nativeElement.value};
      this.add(matChipEvent);
    }
  }

example https://stackblitz.com/edit/angular-rd38q1-jxbjjb?file=src%2Fapp%2Fchips-autocomplete-example.ts示例https://stackblitz.com/edit/angular-rd38q1-jxbjjb?file=src%2Fapp%2Fchips-autocomplete-example.ts

I'll leave one more solution here.我将在这里留下另一个解决方案。

The main problem is that blur on different browsers works a bit differently, so there listener for outside click, which ignore clicks on mat-option and on input :主要问题是模糊在不同浏览器上的工作方式略有不同,因此外部点击的侦听器会忽略mat-optioninput上的点击:

constructor(private eRef: ElementRef, @Inject(DOCUMENT) private _document: Document) {
    this.listenOutsideClick();
  }

private listenOutsideClick(): void {
      fromEvent(this._document, 'click', { passive: false }).pipe(takeUntil(this.isDestroyed$))subscribe((event) => {
        const inside = this.eRef.nativeElement.contains(event.target);
        const clickOnOption = (event.target as HTMLElement).tagName === 'MAT-OPTION';

        if (clickOnOption || inside) {
          // clicked inside;
        } else {
          // clicked outside
          if (this.chipsInput.nativeElement.value) {
            this.add({ 
              input: this.chipsInput.nativeElement, 
              value: this.chipsInput.nativeElement.value 
             } as MatChipInputEvent
           );
           
          }
        }
      })
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM