Website-Suche

html - Material Angular Auto-Vervollständigung: Wie bleibt die mat-option auf dem Bildschirm, nachdem eine Option ausgewählt wurde?


Ich verwende das Material Auto-Complete Angular. Nachdem ich eine Option in meiner mat-option-Liste ausgewählt habe, verschwinden meine mat-options. Ich möchte, dass die Optionen nach der Auswahl bestehen bleiben. Gif zeigt das Problem:

Mein HTML

<div class="col-xl-6 margemColunas">
    <label>Anunciaremos nas contas *</label>
     <input class="form-control inputContasB2W"
          #inputContasB2W
          [formControl]="contasB2WControl"
          [matAutocomplete]="auto"
          (matChipInputTokenEnd)="add($event)">
      <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event, i)">
        <mat-option *ngFor="let contaB2W of contasFiltradas | async" [value]="contaB2W">
          {{contaB2W}}
        </mat-option>
      </mat-autocomplete>
</div>

<div class="col-xl-6 alinhaChips">
  <mat-chip-list>
    <mat-chip
    *ngFor="let contaB2W of produto.contasAnunciarB2W; let j = index"
    [selectable]="selected"
    [removable]="removable"
    (removed)="removeTag(i, j)">
    {{contaB2W}}
    <mat-icon matChipRemove><i class="fa fa-close"></i></mat-icon>
  </mat-chip>
  </mat-chip-list>
</div>

Mein ts:

constructor(){
    this.contasFiltradas = this.contasB2WControl.valueChanges.pipe(
      startWith(null),
      map((nomeConta: string | null) => nomeConta ? this._filter(nomeConta) : this.contasB2W.slice()));
}

  private _filter(value: string): string[] {
    const filterValue = value.toLowerCase();
    return this.contasB2W.filter(conta => conta.toLowerCase().indexOf(filterValue) === 0);
  }

selected(event: MatAutocompleteSelectedEvent, index: number): void {

 this.produtosConfirmadosAnuncio[index].contasAnunciarB2W.push(event.option.viewValue);

    this.inputContasB2W.nativeElement.value = '';

          } 
        }

Antwort #1

Ich habe einen Workaround verwendet, um blur() auszuführen und dann das Eingabefeld wieder mit focus() zu fokussieren.

In ts:

@ViewChild('inputContasB2W') autocompleteInput: ElementRef;

selected(event: MatAutocompleteSelectedEvent) {
  [..do your stuff...]

  this.autocompleteInput.nativeElement.blur();
  setTimeout(() => {
      this.autocompleteInput.nativeElement.focus();
    }, 100
  );
}

Wenn Sie den Eingabetext beibehalten möchten, müssen Sie ihn in _filter() speichern und den Wert erneut festlegen, bevor blur() aufgerufen wird, wie this.contasB2WControl.setValue(this.lastFilterValue);

Antwort #2

Die Lösung ist relativ einfach. Sie müssen die Ausbreitung des Klicks stoppen, aber wenn der Klick das mat-option erreicht, ist es bereits zu spät. Dann wird eine unsichtbare Vorebene mit einem span-Tag hinzugefügt:

...
<mat-autocomplete #auto="matAutocomplete">
  <mat-option *ngFor="let contaB2W of contasFiltradas | async" [value]="contaB2W" 
   style="position: relative;">
    <span style="position: absolute; top: 0; left: 0; bottom: 0; right: 0;"
     (click)="doWhateverWith(contaB2W); $event.stopPropagation()">
      {{contaB2W}}
    </span>
  </mat-option>
</mat-autocomplete>
...
  • Einen span mit dem Stil position: absolute hinzugefügt, bei dem top, left, bottom, right auf 0 gesetzt sind.
  • Den Stil position: relative zu mat-option hinzugefügt, damit sich der Span korrekt erweitert.
  • Das (click)-Ereignis wird hinzugefügt, um das Element im span zu behandeln, da es das letzte sein wird, das das Klick-Ereignis erhält.
  • Das $event.stopPropagation() wird in diesem gleichen span hinzugefügt

Das sollte mehr als genug sein.