簡體   English   中英

Angular材質:墊選不選默認

[英]Angular Material: mat-select not selecting default

我有一個 mat-select,其中選項是數組中定義的所有對象。 我正在嘗試將值設置為默認值之一,但是在頁面呈現時它被選中。

我的 typescript 文件包含:

  public options2 = [
    {"id": 1, "name": "a"},
    {"id": 2, "name": "b"}
  ]
  public selected2 = this.options2[1].id;

我的 HTML 文件包含:

  <div>
    <mat-select
        [(value)]="selected2">
      <mat-option
          *ngFor="let option of options2"
          value="{{ option.id }}">
        {{ option.name }}
      </mat-option>
    </mat-select>
  </div>

我嘗試將selected2mat-option中的value設置為 object 及其 id,並嘗試在mat-select中同時使用[(value)][(ngModel)] ,但均無效。

我正在使用材料版本 2.0.0-beta.10

對模板中的值使用綁定。

value="{{ option.id }}"

應該是

[value]="option.id"

並在您選擇的值中使用ngModel而不是value

<mat-select [(value)]="selected2">

應該是

<mat-select [(ngModel)]="selected2">

完整代碼:

<div>
  <mat-select [(ngModel)]="selected2">
    <mat-option *ngFor="let option of options2" [value]="option.id">{{ option.name }}</mat-option>
  </mat-select>
</div>

版本 2.0.0-beta.12 開始材質選擇現在接受mat-form-field元素作為父元素,因此它與其他材質輸入控件一致。 升級后將div元素替換為mat-form-field元素。

<mat-form-field>
  <mat-select [(ngModel)]="selected2">
    <mat-option *ngFor="let option of options2" [value]="option.id">{{ option.name }}</mat-option>
  </mat-select>
</mat-form-field>

使用compareWith函數將選項值與選定值進行比較。 見這里: https : //material.angular.io/components/select/api#MatSelect

對於具有以下結構的對象:

listOfObjs = [{ name: 'john', id: '1'}, { name: 'jimmy', id: '2'},...]

像這樣定義標記:

<mat-form-field>
  <mat-select
    [compareWith]="compareObjects"
    [(ngModel)]="obj">
       <mat-option  *ngFor="let obj of listOfObjs" [value]="obj">
          {{ obj.name }}
       </mat-option>
    </mat-select>
</mat-form-field>

並像這樣定義比較函數:

compareObjects(o1: any, o2: any): boolean {
  return o1.name === o2.name && o1.id === o2.id;
}

我正在使用 Angular 5 和帶有 mat-select 的反應式形式,但無法獲得上述任何一種解決方案來顯示初始值。

我必須添加 [compareWith] 來處理 mat-select 組件中使用的不同類型。 在內部,似乎 mat-select 使用一個數組來保存選定的值。 如果打開該模式,這可能允許相同的代碼處理多個選擇。

角度選擇控制文檔

這是我的解決方案:

Form Builder 來初始化表單控件:

this.formGroup = this.fb.group({
    country: new FormControl([ this.myRecord.country.id ] ),
    ...
});

然后在你的組件上實現 compareWith 函數:

compareIds(id1: any, id2: any): boolean {
    const a1 = determineId(id1);
    const a2 = determineId(id2);
    return a1 === a2;
}

接下來創建並導出確定 ID 函數(我必須創建一個獨立的函數,以便 mat-select 可以使用它):

export function determineId(id: any): string {
    if (id.constructor.name === 'array' && id.length > 0) {
       return '' + id[0];
    }
    return '' + id;
}

最后將 compareWith 屬性添加到您的 mat-select 中:

<mat-form-field hintLabel="select one">
<mat-select placeholder="Country" formControlName="country" 
    [compareWith]="compareIds">

    <mat-option>None</mat-option>
    <mat-option *ngFor="let country of countries" [value]="country.id">
                        {{ country.name }}
    </mat-option>
</mat-select>
</mat-form-field>

您應該在mat-option中將其綁定為[value] ,如下所示,

<mat-select placeholder="Panel color" [(value)]="selected2">
  <mat-option *ngFor="let option of options2" [value]="option.id">
    {{ option.name }}
  </mat-option>
</mat-select>

現場演示

您可以簡單地實現自己的比較功能

[compareWith]="compareItems"

也請參閱文檔 所以完整的代碼看起來像:

  <div>
    <mat-select
        [(value)]="selected2" [compareWith]="compareItems">
      <mat-option
          *ngFor="let option of options2"
          value="{{ option.id }}">
        {{ option.name }}
      </mat-option>
    </mat-select>
  </div>

並在打字稿文件中:

  compareItems(i1, i2) {
    return i1 && i2 && i1.id===i2.id;
  }

正如在 Angular 6 中已經提到的,在反應形式中使用 ngModel 已被棄用(並在 Angular 7 中刪除),所以我修改了模板和組件如下。

模板:

<mat-form-field>
    <mat-select [formControl]="filter" multiple 
                [compareWith]="compareFn">
        <mat-option *ngFor="let v of values" [value]="v">{{v.label}}</mat-option>
    </mat-select>
</mat-form-field>

組件的主要部分(省略了onChanges等細節):

interface SelectItem {
    label: string;
    value: any;
}

export class FilterComponent implements OnInit {
    filter = new FormControl();

    @Input
    selected: SelectItem[] = [];

    @Input()
    values: SelectItem[] = [];

    constructor() { }

    ngOnInit() {
        this.filter.setValue(this.selected);
    }

    compareFn(v1: SelectItem, v2: SelectItem): boolean {
        return compareFn(v1, v2);
    }
}

function compareFn(v1: SelectItem, v2: SelectItem): boolean {
    return v1 && v2 ? v1.value === v2.value : v1 === v2;
}

注意this.filter.setValue(this.selected) ngOnInit以上。

它似乎適用於 Angular 6。

我就像在這些例子中那樣做。 試圖將 mat-select 的值設置為 mat-options 之一的值。 但是失敗了。

我的錯誤是對數字類型變量執行 [(value)]="someNumberVariable" 而 mat-options 中的變量是字符串。 即使它們在模板中看起來相同,它也不會選擇該選項。

一旦我將 someNumberVariable 解析為字符串,一切就完全沒問題了。

因此,您似乎需要讓 mat-select 和 mat-option 值不僅是相同的數字(如果您要顯示數字),還要讓它們是字符串類型。

我的解決方案是:

<mat-form-field>
  <mat-select #monedaSelect  formControlName="monedaDebito" [attr.disabled]="isLoading" [placeholder]="monedaLabel | async ">
  <mat-option *ngFor="let moneda of monedasList" [value]="moneda.id">{{moneda.detalle}}</mat-option>
</mat-select>

TS:

@ViewChild('monedaSelect') public monedaSelect: MatSelect;
this.genericService.getOpciones().subscribe(res => {

  this.monedasList = res;
  this.monedaSelect._onChange(res[0].id);


});

使用對象:{id: number, detalle: string}

試試這個!

this.selectedObjectList = [{id:1}, {id:2}, {id:3}]
this.allObjectList = [{id:1}, {id:2}, {id:3}, {id:4}, {id:5}]
let newList = this.allObjectList.filter(e => this.selectedObjectList.find(a => e.id == a.id))
this.selectedObjectList = newList

我的解決方案有點棘手和簡單。

<div>
    <mat-select
        [placeholder]="selected2">
      <mat-option
          *ngFor="let option of options2"
          value="{{ option.id }}">
        {{ option.name }}
      </mat-option>
    </mat-select>
  </div>

我只是使用了占位符 材質占位符的默認顏色為light gray 為了使它看起來像選擇了該選項,我只是按如下方式操作 CSS:

::ng-deep .mat-select-placeholder {
    color: black;
}

結合或默認值的設置僅在MatSelect屬性的相當於綁定到MatOption價值屬性。 如果您將項目的caption綁定到mat-option元素的value屬性,您也必須將mat-select上的默認元素設置為項目的caption 如果您將項目的Id綁定到mat-option ,您也必須將id綁定到mat-select ,而不是整個項目、標題或任何其他項目,只有相同的字段。

但是你需要通過綁定來做到這一點 []

我非常仔細地遵循了上述內容,但仍然無法獲得選擇的初始值。

原因是雖然我的綁定值在打字稿中被定義為字符串,但我的后端 API 返回的是一個數字。

Javascript 松散類型只是在運行時更改了類型(沒有錯誤),這阻止了對初始值的選擇。

組件

myBoundValue: string;

模板

<mat-select [(ngModel)]="myBoundValue">

解決方案是更新 API 以返回字符串值。

一個非常簡單的方式實現這一目標是使用formControl具有缺省值,一個內部FormGroup例如(可選)。 這是使用單元選擇器到區域輸入的示例:

ts

H_AREA_UNIT = 1;
M_AREA_UNIT = 2;

exampleForm: FormGroup;

this.exampleForm = this.formBuilder.group({
  areaUnit: [this.H_AREA_UNIT],
});

html

<form [formGroup]="exampleForm">
 <mat-form-field>
   <mat-label>Unit</mat-label>
   <mat-select formControlName="areaUnit">
     <mat-option [value]="H_AREA_UNIT">h</mat-option>
     <mat-option [value]="M_AREA_UNIT">m</mat-option>
   </mat-select>
 </mat-form-field>
</form>

當頁面加載時,我在綁定第一個選項時遇到問題。 下面有幫助我的解決方案

.html

<mat-form-field appearance="outline">    
    <mat-select #teamDropdown 
        [ngModel]="selectedGroupId" (selectionChange)="selectedGroupId=$event.value">
        <mat-option value=undefined>Please Select</mat-option>
        <mat-option *ngFor="let grp of groups" [value]="grp.groupsId">
            {{grp.groupName}}
        </mat-option>
    </mat-select>
</mat-form-field>

.ts

@ViewChild('teamDropdown') teamDropdown: MatSelect;
ngAfterViewInit() {
    setTimeout(() => {
        this.selectTeamDropdown.options.first.select();
    });
}

數字和字符串之間的比較使用 false ,因此,將您選擇的值轉換為 ngOnInit 中的字符串,它將起作用。

我有同樣的問題,我用枚舉填充了 mat-select,使用

Object.keys(MyAwesomeEnum).filter(k => !isNaN(Number(k)));

我有我想選擇的枚舉值......

我花了幾個小時苦苦思索,試圖找出它不起作用的原因。 我在渲染了 mat-select 中使用的所有變量、keys 集合和選定的...這是一個數字) 1=="1" 是假的,因此沒有選擇任何內容。

因此,解決方案將您選擇的值轉換為ngOnInit 中的字符串,它會起作用。

我這樣做了。

<div>
    <mat-select [(ngModel)]="selected">
        <mat-option *ngFor="let option of options" 
            [value]="option.id === selected.id ? selected : option">
            {{ option.name }}
        </mat-option>
    </mat-select>
</div>

通常你可以做[value]="option" ,除非你從某個數據庫中得到你的選項?? 我認為要么是獲取數據的延遲導致它不起作用,要么即使它們相同,獲取的對象在某些方面也有所不同?? 奇怪的是,它最有可能是后者,因為我也嘗試過[value]="option === selected ? selected : option"但它沒有用。

TS

   optionsFG: FormGroup;
   this.optionsFG = this.fb.group({
       optionValue: [null, Validators.required]
   });

   this.optionsFG.get('optionValue').setValue(option[0]); //option is the arrayName

HTML

   <div class="text-right" [formGroup]="optionsFG">
     <mat-form-field>
         <mat-select placeholder="Category" formControlName="optionValue">
           <mat-option *ngFor="let option of options;let i =index" [value]="option">
            {{option.Value}}
          </mat-option>
        </mat-select>
      </mat-form-field>
  </div>

 public options2 = [ {"id": 1, "name": "a"}, {"id": 2, "name": "b"} ] YourFormGroup = FormGroup; mode: 'create' | 'update' = 'create'; constructor(@Inject(MAT_DIALOG_DATA) private defaults: defautValuesCpnt, private fb: FormBuilder, private cd: ChangeDetectorRef) { } ngOnInit() { if (this.defaults) { this.mode = 'update'; } else { this.defaults = {} as Cpnt; } this.YourFormGroup.patchValue({ ... fCtrlName: this.options2.find(x => x.name === this.defaults.name).id, ... }); this.YourFormGroup = this.fb.group({ fCtrlName: [ , Validators.required] }); }
 <div> <mat-select formControlName="fCtrlName"> <mat-option *ngFor="let option of options2" value="{{ option.id }}"> {{ option.name }} </mat-option> </mat-select> </div>

唯一的解決方案是您的表單控件或 mat select 標簽中的 Ng 模型值必須與分配給選項標簽中的值的文本匹配這里是 Ts 文件

selectedFood = 'Tacos';

模板

    <mat-form-field appearance="fill">
      <mat-label>Favorite Food</mat-label>
      <mat-select [(value)]="selectedFood">
        <mat-option value=''>---------</mat-option>
<mat-option value='Tacos'>Tacos</mat-option>
<mat-option value='Pizza'>Pizza</mat-option>
        
      </mat-select>
    </mat-form-field>
    <p>You selected: {{selectedFood}}</p>

在使用角度材質選擇時,使用compareWith函數比較對象是一個很好的做法。 如果您想了解更多關於如何使用 mat-select 的信息,您可以查看以下鏈接: 比較函數在角度材料選擇中的重要性

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM