オプションが配列で定義されたすべてのオブジェクトであるところに、私は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>
selected2
のmat-option
とvalue
をオブジェクトとそのidの両方に設定してみました。そしてmat-select
で[(value)]
と[(ngModel)]
の両方を使ってみましたが、どれもうまくいきません。
材料バージョン2.0.0-beta10を使用しています
ありがとう
テンプレートの値にバインディングを使用してください。
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>
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と一緒に使っていますが、初期値を表示するために上記の解決策のどちらも得ることができませんでした。
Mat-selectコンポーネント内で使用されているさまざまな型を処理するために[compareWith]を追加する必要がありました。内部的には、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;
}
次に、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>
以下のように[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>
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でうまくいくようです。
私の解決策は少しトリッキーで簡単です。
<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;
}
私にとっての解決策は次のとおりです。
<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}を使用してください
これを試して!
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
これらの例と同じようにしました。 mat-selectの値をmat-optionsの1つの値に設定しようとしました。しかし失敗しました。
私の間違いは[(value)] = "someNumberVariable"を数値型変数にすることでしたが、mat-optionsの中のものは文字列でした。テンプレート内で同じように見えても、そのオプションは選択されません。
SomeNumberVariableを文字列に解析したら、すべて問題ありませんでした。
そのため、mat-selectとmat-optionの値を同じ数にする必要があるだけでなく(数字を表示する場合)、それらを文字列型にする必要があるようです。
あなたは単にあなた自身の比較機能を実装することができます
[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;
}