мат-выбор панели всегда ложно

#angular #unit-testing #angular-material #jasmine #mat-select

Вопрос:

У меня есть следующий шаблон:

   <mat-select #select>
      <mat-option *ngFor="let option of optionsData">
        {{ select.panelOpen ? option.viewValue : option.value }}
      </mat-option>
  </mat-select>
 

И следующий тест, который не проходит:

 it('should populate options list with view values', async () => {
    const expected = optionsData.map(o => o.viewValue);
    const select = de.query(By.css('.mat-select')).nativeElement;

    select.click();
    fixture.detectChanges();

    await fixture.whenStable().then(() => {
      for (const option of select.children) {
        expect(expected.findIndex(e => e === option.textContent)).toBeGreaterThan(-1);
      }
    });
  });
 

Но если я изменю первую строку в тесте на:

const expected = optionsData.map(o => o.value)

Тогда испытание пройдет. Это означает, что panelOpen всегда имеет значение false и получает только значение вместо значения представления, даже если я нажал на элемент «выбрать».

Почему функция click() не меняет значение panelOpen с false на true?

Ответ №1:

Я исправил эту проблему с помощью директивы

 import { OnInit, Directive, EventEmitter, Output } from '@angular/core';
import { MatSelect } from '@angular/material/select';

@Directive({
  selector: '[athMatOptionDirective]'
})
export class MatOptionDirective implements OnInit {
  @Output() matOptionState: EventEmitter<any> = new EventEmitter();
  constructor(private matSelect: MatSelect) { }
  ngOnInit() {
    this.matSelect.openedChange.subscribe(isOpen => {
      if(isOpen) return this.matOptionState.emit(true)
      return this.matOptionState.emit(false)
    })
  }
}
 

в вашем html-компоненте:

 <mat-form-field>
  <mat-select athMatOptionDirective (matOptionState)="getMatOptionState(event)">
  </mat-select>
</mat-form-field
 

компонент машинописного текста:

 getMatOptionState(event) {
   console.log('is mat-option open?', event)
}
 

Большое спасибо Юрию Штрумпфлонеру (https://juristr.com/blog/2020/06/access-material-select-options)
пример здесь: stackblitz