Angular5中Bootstrap4下拉框内嵌Material自动完成组件时下拉框意外关闭问题
Hey there! Let's figure out why your Bootstrap dropdown keeps closing when you pick an option from your Angular Material autocomplete, and fix it right up.
What's Going On
Bootstrap dropdowns have a default behavior: they close whenever you click inside their dropdown menu area. When you click a Material autocomplete option, that click event "bubbles up" through the DOM to the Bootstrap dropdown container. Bootstrap sees that click and triggers the dropdown close action—even though your autocomplete is working perfectly on its own.
Solution 1: Stop Event Bubbling (Recommended)
The simplest fix is to stop the click event from the autocomplete option from reaching the Bootstrap dropdown. Here's how to do it:
First, update your mat-option template to pass the click event to your component:
<mat-option *ngFor="let option of filteredOptions | async" [value]="option" (click)="selectOption(option, $event)" > {{ option }} </mat-option>
Then, in your component TypeScript file, add the stopPropagation() call to block the event from bubbling up:
selectOption(option: any, event: Event): void { // Prevent the click from reaching Bootstrap's dropdown handler event.stopPropagation(); // Add your existing logic here (like setting the form control value) this.yourFormControl.setValue(option); }
Solution 2: Override Bootstrap's Dropdown Close Behavior
If stopping propagation doesn't fit your use case, you can tell Bootstrap to ignore clicks inside your autocomplete area.
First, add a unique class to your autocomplete's container (e.g., autocomplete-in-dropdown). Then, use Angular's ElementRef to listen for Bootstrap's hide.bs.dropdown event and block it when needed:
import { Component, ElementRef, AfterViewInit } from '@angular/core'; @Component({ selector: 'your-filter-component', templateUrl: './your-filter.component.html' }) export class YourFilterComponent implements AfterViewInit { constructor(private el: ElementRef) {} ngAfterViewInit(): void { const dropdownBtn = this.el.nativeElement.querySelector('#user-filter'); dropdownBtn.addEventListener('hide.bs.dropdown', (event: Event) => { // Check if the click happened inside the autocomplete const clickedInAutocomplete = (event.target as HTMLElement).closest('.autocomplete-in-dropdown, .mat-autocomplete-panel'); if (clickedInAutocomplete) { // Block Bootstrap from closing the dropdown event.preventDefault(); } }); } }
Quick Note
If you're using Bootstrap with jQuery (the default setup), be mindful of potential conflicts with Angular's event handling. Solution 1 is more aligned with Angular's best practices since it avoids direct DOM manipulation with jQuery.
内容的提问来源于stack exchange,提问作者RasMason

