Angular Material, Mat Chips Autocomplete Bug, matChipInputTokenEnd executed before optionSelected
在输入中键入一些文本并通过按Enter键从自动完成功能中选择一个选项时,两个字符串都保存为筹码。 图片在这里
但是,使用鼠标从自动完成功能中选择一个选项时,不会发生这种情况。
在Angular Material Autocomplete Chips上提供的示例中,在所述情况下,首先触发optionSelected,而在本地计算机上的同一代码中,它在matChipInputTokenEnd之后执行,从而导致错误。
有没有人遇到这个问题?
关于选择事件,当您按ENTER键时,将触发输入中的matChipInputTokenEnd和mat-autocomplete中的optionSelected。通常,这会首先使用optionSelected发生,因此当输入事件触发时,芯片将已经添加,而输入将没有值可添加。这就是为什么用鼠标单击不会出现此问题的原因,因为只会触发optionSelected事件。
现在,我通常说是因为在模块导入的组件上也遇到了这个问题。如果是这种情况,则可能是一个错误。
但是,我确实找到了快速解决方案。我所做的是检查mat-autocomplete对话框是否打开,并防止mat-chip-input添加新元素。也可以检查选项列表中的选定项目,但是性能较差,而不是我想要的行为。
希望这可以帮助:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @ViewChild('chipAutocomplete') chipAutocomplete: MatAutocomplete; addElement(event: MatChipInputEvent) { if ((event.value || '').trim() && !this.chipAutocomplete.isOpen) { this.value.push({ name: event.value.trim() }); } if (event.input) { event.input.value = ''; } this.chipInputControl.setValue(null); } |
我结合了@ama和其他答案,以获得我认为您正在描述的功能。关键是结合使用optionActivated全局变量和手动关闭自动完成面板:
1 2 3 | <input #autoInput (matChipInputTokenEnd)="inputTokenEnd($event)" ... > <mat-autocomplete (optionActivated)="optionActivated($event)" (optionSelected)="optionSelected($event)... > |
1 2 3 4 5 6 7 | autocompleteTagsOptionActivated = false; optionActivated(event: MatAutocompleteActivatedEvent) { if (event.option) { this.autocompleteTagsOptionActivated = true; } } |
1 | @ViewChild('autoInput', { read: MatAutocompleteTrigger }) matAutocompleteTrigger: MatAutocompleteTrigger; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | inputTokenEnd(event: MatChipInputEvent): void { const input = event.input; const value = event.value; if ((value || '').trim() && !this.autocompleteTagsOptionActivated) { this.value.push(value.trim()); } // Reset the input value if (input) { input.value = ''; } this.controlsForm.autocomplete.setValue(null); // If no autocomplete options were activated, then issue the command to close the panel. The enter key that // triggers the input will inadventantly open the panel if (!this.autocompleteTagsOptionActivated) { this.matAutocompleteTrigger.closePanel() } } |
1 2 3 4 5 | optionSelected(event: MatAutocompleteSelectedEvent): void { this.autocompleteTagsOptionActivated = false; ... } |
尽管AndréDias提出的解决方案在您有严格的选择选择时可以使用,但如果您需要在选择中添加一个子字符串(在自动完成中仅包含" javascript"的情况下可以考虑" java"),则无法使用。为此,您还可以将
html部分:
1 2 3 4 5 6 7 8 | <mat-autocomplete #auto="matAutocomplete" (optionActivated)="optionActivated($event)" (optionSelected)="selectedTag($event)"> <mat-option *ngFor="let tag of filteredTags | async" [value]="tag"> {{ tag }} </mat-option> </mat-autocomplete> |
组成部分:
1 2 3 4 5 6 7 | autocompleteTagsOptionActivated = false; optionActivated($event: MatAutocompleteActivatedEvent) { if ($event.option) { this.autocompleteTagsOptionActivated = true; } } |
然后检查布尔变量并将其从键盘选择中实际添加时设置为false:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | addTag(event: MatChipInputEvent): void { const input = event.input; const value = event.value; if ((value || '').trim() && !this.autocompleteTagsOptionActivated) { this.formArrayTags.push(this.formBuilder.control(value.trim().toLowerCase())); } // Reset the input value if (input) { input.value = ''; } this.tagsControl.setValue(null); this.formArrayTags.markAsDirty(); } |
1 2 3 4 5 6 | selectedTag(event: MatAutocompleteSelectedEvent): void { this.formArrayTags.push(this.formBuilder.control(event.option.viewValue)); this.tagInput.nativeElement.value = ''; this.tagsControl.setValue(null); this.autocompleteTagsOptionActivated = false; } |
对我来说很好。在这里,我附加了meterial.angular.io提供的示例链接
https://stackblitz.com/angular/klblpljogjd?file=app%2Fchips-autocomplete-example.ts