【问题标题】:Angular Material Autocomplete: closePanel not workingAngular Material Autocomplete:closePanel 不工作
【发布时间】:2022-12-20 22:14:04
【问题描述】:

我正在处理一个对话框中的表单,其中一个表单字段使用 mat-autocomplete。提交的表格被添加到表格中。当用户单击表格的一行时,表单对话框再次打开,他或她可以编辑之前提交的表单。

当前行为:当用户打开表单时,自动完成字段已经填充了先前提交的值,并且自动完成面板打开

通缉行为:同样的事情,但自动完成面板关闭。

我想做什么:@ViewChild(MatAutocompleteTrigger) autoComplete: MatAutocompleteTrigger; 接着 this.autoComplete.closePanel();

我试过在 HTML 模板中输入 #autoComplete#MatAutocompleteTrigger 选择器。

我得到的实际错误是ERROR TypeError: Cannot read properties of undefined (reading 'closePanel'),因为autocomplete 未定义。

我也尝试过这种方法: HTML:

<input #autoCompleteInput type="text" [matAutocomplete]="auto"/>

TS:

@ViewChild('autoCompleteInput', { read: MatAutocompleteTrigger }) 
autoComplete: MatAutocompleteTrigger;

我看到了一些关于它的问题:hereherehere,但无法让它工作。

代码如下:

HTML(仅显示自动完成部分)

    <mat-form-field class="top-form-field" appearance="outline">
      <mat-label>Brigada</mat-label>
      <input matInput
             #autoComplete
             aria-label="Brigada"
             [matAutocomplete]="auto"
             formControlName="nome_brigada">
      <mat-autocomplete #auto="matAutocomplete">
        <mat-option *ngFor="let brigade of filteredBrigades | async" [value]="brigade.name">
          <img class="option-img" aria-hidden [src]="brigade.typeIcon" height="25">
          <span>{{brigade.name}}</span> |
          <small>{{brigade.category}}</small>
          <span *ngIf="brigade.plate">
            | <small>{{brigade.plate}}</small>
          </span>
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>

TS:(没有进口)

OBS:当“行”不为空时,用户在表格中单击并将编辑先前提交的表单(我想要关闭面板的情况)

export interface Brigade {
  type: string;
  typeIcon: string;
  name: string;
  category: string;
  filterString: string;
  id_brigada: string;
  plate: string;
}

@Component({
  selector: 'select-brigade-dialog',
  templateUrl: 'select-brigade-dialog.html',
})
export class SelectBrigadeDialog {

  @ViewChild(MatAutocompleteTrigger) autoComplete: MatAutocompleteTrigger;

  public brigadeForm: FormGroup;
  brigadeCtrl = new FormControl('', [Validators.required]);
  filteredBrigades: Observable<Brigade[]>;

  public brigades: Brigade[] = [];

  public tipos_brigada:string[];
  public categorias_brigada:string[];
  public nomes_brigada: string[];

  combateChecked: boolean;
  rescaldoChecked: boolean;
  
  constructor(
    @Inject(MAT_DIALOG_DATA)
    public data: any,
    public fb: FormBuilder,
    private dtValidators: DatetimeValidators,
    private amplitude: AmplitudeService
  ) {

    this.combateChecked = false;
    this.rescaldoChecked = false;

    for (let b of data.brigadas){
      this.brigades.push({
        type: b['tipo_brigada'],
        typeIcon: brigadeIconMap[b['id_tipo_brigada']],
        name: b['nome_brigada'],
        category: b['categoria_brigada'],
        filterString: b['nome_brigada'] + b['placa'] + b['categoria_brigada'],
        id_brigada: b['id_brigada'],
        plate: b['placa']
      })
    }

    this.brigades.sort((a, b) => a.name.localeCompare(b.name));

    if (data.row === null){
      this.filterBrigades('');
    } else {
      this.filterBrigades(data.row['nome_brigada']);
    }

    let id_acionamento = `${data.id_report}_${data.len_acionamentos}`

    this.initForm(data.row, id_acionamento);
  }

  filterBrigades(nome_brigada) {
    this.filteredBrigades = this.brigadeCtrl.valueChanges.pipe(
      startWith(nome_brigada),
      map(brigade => (brigade ? this._filterBrigades(brigade) : this.brigades.slice())),
      );
    }
    
  private _filterBrigades(value: string): Brigade[] {
    const filterValue = value.toLowerCase();
    return this.brigades.filter(brigade => brigade.filterString.toLowerCase().includes(filterValue)).sort((a, b) => a.name.localeCompare(b.name));
  }
  
  initForm(row, id_acionamento){
    let datetime_now = formatDate(new Date(), 'yyyy-MM-ddTHH:mm', 'en-US');
    let dt_midnight = this.setMidnight();

    let dt_validators = [
      this.dtValidators.dtAcionamento(),
      this.dtValidators.dtCombate(),
      this.dtValidators.dtRescaldo(),
      this.dtValidators.dtChegadaCombate(),
      this.dtValidators.dtChegadaRescaldo(),
      this.dtValidators.dtFuturo(dt_midnight)
    ]
    
    if (row === null){
      this.brigadeForm = this.fb.group({
        nome_brigada: this.brigadeCtrl,
        contagem_equipe:['1',[Validators.required, Validators.min(1)]],
        dt_acionamento:[`${datetime_now}`,[Validators.required]],
        dt_chegada:[''],
        combate: false,
        dt_inicio_combate:[''],
        dt_fim_combate:[''],
        rescaldo: false,
        dt_inicio_rescaldo:[''],
        dt_fim_rescaldo:[''],
        id_acionamento:[id_acionamento],
        id_brigada: ['']
      },{
        validators: dt_validators,
      });
    } else {
      if (row['dt_inicio_combate'] !== null && row['dt_inicio_combate'] !== ''){
        this.combateChecked = true;
      };
      if (row['dt_inicio_rescaldo'] !== null && row['dt_inicio_rescaldo'] !== ''){
        this.rescaldoChecked = true;
      };
      this.brigadeForm = this.fb.group({
        nome_brigada: [row['nome_brigada'],[Validators.required]],
        contagem_equipe:[row['contagem_equipe'],[Validators.required, Validators.min(1)]],
        dt_acionamento:[row['dt_acionamento'],[Validators.required]],
        dt_chegada:[row['dt_chegada']],
        combate: this.combateChecked,
        dt_inicio_combate:[row['dt_inicio_combate']],
        dt_fim_combate:[row['dt_fim_combate']],
        rescaldo: this.rescaldoChecked,
        dt_inicio_rescaldo: [row['dt_inicio_rescaldo']],
        dt_fim_rescaldo: [row['dt_fim_rescaldo']],
        id_acionamento: [row['id_acionamento']],
        id_brigada: [row['id_brigada']]
      },{
        validators: dt_validators,
      });
      console.log('autocomplete: ', this.autoComplete)
      this.autoComplete.closePanel();
    }
  }

【问题讨论】:

  • “当用户打开表单时,自动完成字段已经填充了先前提交的值,并且自动完成面板已打开”你的意思是说当用户点击自动完成时面板不需要打开?
  • 由于自动完成是第一个表单字段,实际上当表单对话框打开时,焦点转到自动完成,用户没有点击/操作。无论表单焦点如何,我都希望在面板关闭的情况下初始化表单

标签: angular angular-material


【解决方案1】:
let dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
  width: '250px',
  data: { name: this.name, animal: this.animal },
  autoFocus: false   <============================== this line
});

也许如果我没记错的话你的自动对焦有问题 首先控制。所以,使用上面你可以处理你的任务。如果你仍然没有运气,请告诉我。快乐的编码。

【讨论】:

  • 有效!我被 closePanel 困住了,没有考虑焦点。谢谢 :)
猜你喜欢
  • 2018-07-22
  • 2020-12-01
  • 2020-04-04
  • 2021-04-14
  • 2020-02-01
  • 2018-07-03
  • 2016-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多