web-dev-qa-db-ja.com

Angular 材質:マットセレクト、デフォルトを選択しない

オプションが配列で定義されたすべてのオブジェクトであるところに、私はmat-selectを持っています。値をデフォルトのオプションの1つに設定しようとしていますが、ページがレンダリングされるときに選択されたままになっています。

私の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-optionvalueをオブジェクトとそのidの両方に設定してみました。そしてmat-select[(value)][(ngModel)]の両方を使ってみましたが、どれもうまくいきません。

材料バージョン2.0.0-beta10を使用しています

ありがとう

58
William Moore

テンプレートの値にバインディングを使用してください。

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>

version 2.0.0-beta.12 についてのメモとして、 material select は親要素として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>
76
Igor

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;
}
42
Badis Merabet

私はAngular 5と反応型のフォームをmat-selectと一緒に使っていますが、初期値を表示するために上記の解決策のどちらも得ることができませんでした。

Mat-selectコンポーネント内で使用されているさまざまな型を処理するために[compareWith]を追加する必要がありました。内部的には、mat-selectは選択された値を保持するために配列を使います。そのモードがオンになっている場合、これは同じコードが複数の選択で動作するのを許可する可能性があります。

Angularコントロールドキュメントの選択

これが私の解決策です:

フォームコントロールを初期化するための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;
}

次に、calculateId関数を作成してエクスポートします(mat-selectが使用できるように、スタンドアロン関数を作成する必要がありました)。

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

最後に、compareWith属性をマット選択に追加します。

<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>
13
Heather92065

以下のように[value]の中でmat-optionとしてバインドする必要があります。

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

LIVE DEMO

12
Aravind

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でうまくいくようです。

3
mp31415

私の解決策は少しトリッキーで簡単です。

<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;
}
2

私にとっての解決策は次のとおりです。

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


});

Object:{id:number、detalle:string}を使用してください

2
Seba Arce

これを試して!

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
1
Facu Quintana

これらの例と同じようにしました。 mat-selectの値をmat-optionsの1つの値に設定しようとしました。しかし失敗しました。

私の間違いは[(value)] = "someNumberVariable"を数値型変数にすることでしたが、mat-optionsの中のものは文字列でした。テンプレート内で同じように見えても、そのオプションは選択されません。

SomeNumberVariableを文字列に解析したら、すべて問題ありませんでした。

そのため、mat-selectとmat-optionの値を同じ数にする必要があるだけでなく(数字を表示する場合)、それらを文字列型にする必要があるようです。

1
jg80

あなたは単にあなた自身の比較機能を実装することができます

[compareWith]="compareItems"

-ocu も参照してください。したがって、完全なコードは次のようになります。

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

そしてTypeScriptファイルで:

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