0

我有以下模板:

  <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 并且仅获取值而不是viewValue,即使我单击了“选择”元素。

为什么 click() 不会将panelOpen从 false 更改为 true?

4

1 回答 1

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)
}

非常感谢 Juri Strumpflohner ( https://juristr.com/blog/2020/06/access-material-select-options ) 这里的例子:stackblitz

于 2021-09-29T12:49:19.450 回答