首页 > 解决方案 > Material Select Default Selected item第二次不起作用

问题描述

如何使 Angular 材质选择组件在更改后返回其选定的默认值?它在初始化时起作用,但在 UI 屏幕中手动更改值后不起作用。

尝试创建一个按钮,使其恢复默认值。有没有办法使用 NgOnChanges?已经在使用 get setter。

HTML:

<div class="dropdown-cont">
    <mat-form-field appearance="outline">
        <mat-label>{{label}}</mat-label>
        <mat-select
            disableOptionCentering
            [disabled]="disabled"
            [ngStyle]="styles"
            [(ngModel)]="selectedItem"
            (selectionChange)="selectedItemChanged($event)"
            >
            <mat-option [value]="defaultItem[txtValue]">{{defaultItem[txtField]}}</mat-option>
            <mat-option
                *ngFor="let item of listItems"
                [value]="item[txtValue]"
            >
            {{item[txtField]}}
            </mat-option>
        </mat-select>
        <mat-hint>{{hint}}</mat-hint>
    </mat-form-field>
</div>

打字稿:

import { Component, OnInit, Input, EventEmitter, Output, forwardRef } from '@angular/core';
import { DropdownItem, DropdownComponent } from '../dropdown/dropdown.component';
import { NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-drop-down',
  templateUrl: './drop-down.component.html',
  styleUrls: ['./drop-down.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => DropdownComponent),
      multi: true
    }
  ]
})

export class DropDownComponent implements OnInit {
  ngOnInit() {
  }

  //#region Members

  private _listItems = [];

  onChange: any = () => { };

  onTouch: any = () => { };

  //#endregion

  //#region Inputs

  @Input()
  set listItems(data: Array<DropdownItem>) {
    this._listItems = data;
    this.selectedItem = undefined;
  }
  get listItems() {
    return this._listItems;
  }
  @Input() label = '';
  @Input() styles: any = {};
  @Input() txtField: any;
  @Input() txtValue: any;
  @Input() disabled: boolean;
  @Input() defaultItem: object;
  @Input() selectedItem: DropdownItem;
  @Input() primitive = false;
  @Input() hint = '';
  //#endregion

  //#region Outputs

  @Output() selectedItemOutput = new EventEmitter();

  //#endregion

  //#region ControlValueAccessor

  set value(val) {
    this.selectedItem = val;

    this.onChange(val);

    this.onTouch(val);
  }

  writeValue(obj: any): void {
    this.selectedItem = obj;
    this.value = obj;
  }
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }
  registerOnTouched(fn: any): void {
    this.onTouch = fn;
  }
  setDisabledState?(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }

  //#endregion

  //#region Event Handlers

  selectedItemChanged(selectItem) {
    this.onChange();
    let outputData: any;
    if (selectItem.value == this.defaultItem[this.txtValue]) {
      outputData = this.defaultItem;
    } else {
      outputData = this.listItems.find(x => x[this.txtValue] == selectItem.value);
    }

    this.selectedItemOutput.emit(outputData);
  }

  //#endregion

}

标签: angulartypescriptangular-materialangular8

解决方案


看看这个StackBlitz 链接

<mat-select
        [(ngModel)]="selectedItem.txtValue"
        (selectionChange)="selectedItemChanged($event)" >
        <mat-option [value]="selectedItem.txtValue">
                 {{selectedItem.txtField}}
        </mat-option>
        <mat-option *ngFor="let item of listItems" [value]="item.txtValue" >
                 {{item.txtField}}
        </mat-option>
</mat-select>

 <button (click)="defaultState()" > Default State </button>

然后,在您的 component.ts 文件中...

selectedItem = {txtValue:'d', txtField: 'default'};
listItems =[{
   txtValue: '1',
   txtField: 'one'
}]

selectedItemChanged(event){
   console.log(event.value)
}
// This method set default state of dropDown select by clicking button
defaultState(){
  this.selectedItem = {txtValue:'d', txtField: 'default'};
}

推荐阅读