简体   繁体   中英

mat-autocomplete not working inside mat-table

Issue description:

I have defined multiple mat-autocomplete as shown below with almost identical code to fetch data from multiple list.

<div class="col-md-4">
<mat-form-field class="example-full-width">
  <mat-label>Level</mat-label>
  <input matInput name="level" aria-label="Level" [matAutocomplete]="auto" 
  [(ngModel)]="element.Level" (ngModelChange)="filtredSelection($event,'Levels')">
  <mat-autocomplete #auto="matAutocomplete" [displayWith]="displaySelectedLevel" >
    <mat-option *ngFor="let level of filtredLevels | async" [value] = "element.Level">
      <div (click)="levelsOptionClicked($event, element, level)">
        <span>{{level.Code}}</span> |
        <small>{{level.Description}}</small>
      </div>
    </mat-option>
  </mat-autocomplete>
</mat-form-field>
</div>
<div class="col-md-8">
<mat-form-field class="example-full-width">
  <mat-label>Location</mat-label>
  <input matInput name="location" aria-label="Location" [matAutocomplete]="auto" 
  [(ngModel)]="element.Location" (ngModelChange)="filtredSelection($event,'Locations')">
  <mat-autocomplete #auto="matAutocomplete" [displayWith]="displaySelectedLocation" >
    <mat-option *ngFor="let location of filtredLocations | async" [value] = "element.Location">
      <div (click)="locationsOptionClicked($event, element, location)">
        <span>{{location.Code}}</span> |
        <small>{{location.Description}}</small>
      </div>
    </mat-option>
  </mat-autocomplete>
</mat-form-field>
</div>

The first one works, and shows the selection list, however on the second one I can see that its making the call and getting the results, but the drop down selection do not show correctly.

Strange issue I notice is that when I click and filter the item on the first control which works and then move to the second control, it shows the options from first control in the second control's dropdown.

Here is my control logic

  applyLevelSelectionFilter(filter: string) {
    if (filter?.length >= 3) {
     const promise = this.dataService.getAllLevels(filter).then<Level[]>(
        data => {
          this.isLoadingFilters = false;
          let result = [];
          if (data) {
            const levels = (data as any).value;
            this.logger.log('fetched filtred levels', levels);
            result = (data as any).value;
          }
          return result;

        });
        this.filtredLevels = from(promise);
    } else {
      this.logger.log('search string less than 3 char, clearing the level selection', filter);
      return of([]);
    }
  }

  applyLocationSelectionFilter(filter: string) {
    if (filter?.length >= 3) {
      this.isLoadingFilters = true;
      const promise = this.dataService.getAllLocations(filter).then<Location[]>(
        data => {
          let result = [];
          if (data) {
            const locations = (data as any).value;
            this.logger.log('fetched filtred locations', locations);
            result = (data as any).value;
          }
          return result;

        });
        this.filtredLocations = from(promise);
    } else {
      this.logger.log('search string less than 3 char, clearing the location selection', filter);
      return of([]);
    }
  }

  filtredSelection(filter, entitySet){
    this.logger.log('Triggring filtered list update', filter, entitySet);
    if (entitySet === 'Levels' ) {
      this.applyLevelSelectionFilter(filter);
    } else if (entitySet === 'Locations') {
      this.applyLocationSelectionFilter(filter);
    } else {
      this.logger.error('Triggring filtered list update with unknown entity set', filter, entitySet);
    }
  }

I am unable to find what is wrong here.

Update 1

I have recreated it here . click on the row to expand and see the edit fields.

Try to define a different template reference for each autocomplete, I mean change #auto="matAutocomplete" to #location="matAutocomplete" for exemple and adjust [matAutocomplete]="location" in the input. find out more information here https://angular.io/guide/template-reference-variables about template references and here how to use them in the mat auto complete https://material.angular.io/components/autocomplete/overview

Also, instead of looping and changing the original arrays, I reworked the filter function to always return a new array depending on input's ngModel, you can try it in the stackblitz it's fully working.

You can find the correction here on stackblitz forked from your stackblitz

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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