angular добавить пустую опцию mat во все ненужные mat-select в моем приложении - PullRequest
3 голосов
/ 31 марта 2020

Как я могу добавить динамически пустое mat-option ко всем необязательным mat-select в моем приложении.

вроде:

 <mat-form-field appearance="outline">
         <mat-label>HMO</mat-label>
         <mat-select>
              <--how can I add this dynamically-->
              <mat-option>--</mat-option>
              <mat-option *ngFor="let hmo of HMOList"
                              [value]="hmo.Code">
                    {{ hmo.Desc }}
              </mat-option>
         </mat-select>
  </mat-form-field>

любая идея?

Ответы [ 5 ]

1 голос
/ 10 апреля 2020

Вот пример stackblitz , основанный на различных ответах здесь.

Директива ниже применяется к mat-select, поэтому вам не нужно добавлять никаких дополнительных атрибутов. Он использует атрибут required для выбора, чтобы знать, добавлять ли какие-либо пустые опции при открытии раскрывающегося списка.

Примечание : Вы не можете легко добавить элементы в базовый список используемых опций мата компонентом mat-select, поэтому элементы опций mat добавляются вручную, и события также должны быть связаны вручную (я сделал это для события click);

import { Directive, HostListener, OnInit, Renderer2, ElementRef, AfterViewInit } from '@angular/core';
import { MatSelect } from '@angular/material/select';

import { Directive, HostListener, OnInit, Renderer2, ElementRef, AfterViewInit } from '@angular/core';
import { MatSelect } from '@angular/material/select';

@Directive({
  selector: 'mat-select'
})
export class OptionalMatSelectDirective {

  constructor(private matSelect: MatSelect, private elementRef: ElementRef,
  private renderer: Renderer2) { }

    @HostListener('openedChange', ['$event'])
    onOpenedChange( isOpened : boolean) 
    {

      if(!isOpened || this.matSelect.required)
      {
        return; //Closing panel, or select is required
      }
      //Manually create a mat option DOM element
      let matOption = this.renderer.createElement("mat-option");
      this.renderer.setAttribute(matOption, 'class', 'mat-option');

      //Bind events to the new mat option
      this.renderer.listen(matOption,'click', ()=>
      {
        this.matSelect.value = "";
        this.matSelect.close();
      });

      //Try to add the new mat option in first position of the list
      let panel= document.querySelector('.mat-select-panel');
      if(!panel)
      {
        throw "Cannot find mat select panel";
      }
      this.renderer.insertBefore(panel,matOption, panel.firstChild);


  }
}
0 голосов
/ 09 апреля 2020

Я могу получить это далеко:

  • Создать новую директиву с селектором как mat-select
  • Получить ссылку на элемент MatSelect через ContentChildren
  • Я мог бы использовать это, чтобы добавить параметр в массив _results на MatSelect, но он не обновляет DOM, так что вам нужно выяснить это

Это не потребовать каких-либо изменений на HTML.

Ниже, насколько я смог получить за короткий промежуток времени. Будет лучший способ добавить опцию в MatSelect - вам, в основном, нужно посмотреть исходные файлы Angular и посмотреть, как они добавляют MatOption, а затем повторить это в вашей директиве.

Хорошо удачи!

@Directive({
  selector: 'mat-select',
  exportAs: 'myMatSelect'
})
export class MyMatSelectDirective {

  constructor(
    public changeDetectorRef: ChangeDetectorRef
  ) { }

  select: MatSelect;

  @ContentChildren(MatSelect) set list(select: QueryList<MatSelect>) {
    this.select = select.first;

    // One possible option is to subscribe to the openChange event
    this.select.openedChange.subscribe(open => {
      let opt = document.createElement("mat-option");
      opt.innerHTML = "--";
      (<any>this.select.options)._results.unshift(new MatOption(new ElementRef(opt), this.changeDetectorRef, this.select, null));
      console.log(this.select)
    })
  }
}

0 голосов
/ 05 апреля 2020

Есть несколько способов выполнить sh эту задачу,

Первый подход Сначала вы можете создать свойство в классе компонентов и управлять видимостью mat-option по умолчанию. И привяжите это свойство в шаблон, как показано ниже:

Шаблон

  <mat-select [required]="isRequired">
    <mat-option *ngIf="isRequired">---</mat-option>
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{food.viewValue}}
    </mat-option>
  </mat-select>

Класс компонента

export class SelectOverviewExample {
  isRequired = true;
  foods: Food[] = [
    {value: 'steak-0', viewValue: 'Steak'},
    {value: 'pizza-1', viewValue: 'Pizza'},
    {value: 'tacos-2', viewValue: 'Tacos'}
  ];
}

Пожалуйста, используйте следующую рабочую ссылку - https://stackblitz.com/edit/angular-azkmrp

Второй подход Второй подход заключается в том, что вы можете использовать переменную ссылки на шаблон только в шаблоне и использовать ее, чтобы добавить опцию mat по умолчанию. Здесь я создал переменную ссылки шаблона #matselect и добавил обязательный атрибут. Использование этой ссылочной переменной шаблона с опцией mat по умолчанию. Просто переключите необходимый атрибут для проверки.

 <mat-select #matselect required>
    <mat-option *ngIf="matselect.required">---</mat-option>
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{food.viewValue}}
    </mat-option>
  </mat-select>

Рабочий код можно найти здесь: https://stackblitz.com/edit/angular-zpvjf2

0 голосов
/ 05 апреля 2020

Вы можете использовать функцию javascript unshift, чтобы добавить первое значение для всех необходимых элементов выбора.

HMOList.unshift( {code:'', desc:'--'});

Если вы хотите добавить опцию того же типа в каждом поле выбора. Я внес изменения в stackblitz.

См. здесь

0 голосов
/ 05 апреля 2020

Почему бы просто не изменить HMOList за сценой, как HMOList = [ ...HMOList, { code: 'None', Desc: ''} ] (или наоборот, так как сначала вы хотите вариант по умолчанию)? Это кажется немного хакерским, но это также кажется самым простым. Или лучше сохранить дополнительный массив для mat-select, если мы хотим сохранить исходный массив, поскольку мы копируем все в любом случае, чтобы убедиться, что пользовательский интерфейс и все остальное будет обновлено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...