オプションがすべて配列で定義されたオブジェクトである mat-select があります。 デフォルトの値をオプションのいずれかに設定しようとしていますが、ページがレンダリングされるときに選択されたままになっています。
私のタイプスクリプトファイルには
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>
mat-optionの
selected2と
valueにオブジェクトとそのidを設定し、
mat-selectに
[(value)]と
[(ngModel)]`の両方を使用してみましたが、どれもうまくいきません。
マテリアルのバージョンは2.0.0-beta.10です。
テンプレートの値にバインディングを使用します。
value="{{ option.id }}"
は
[value]="option.id"
また、selected value では value
の代わりに ngModel
を使用します。
<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
、A関数を使用して、オプション値と選択した値を比較します。 ここを参照してください: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;
}
Angular5とreactive forms with mat-selectを使っていますが、上記のどちらの方法でも初期値を表示させることができません。
mat-selectコンポーネント内で使用されている異なる型に対処するために、[compareWith]を追加する必要がありました。内部的には、mat-selectは選択された値を保持するために配列を使っているようです。このモードがオンになっている場合、同じコードが複数の選択で動作するようになるようです。
Angular Select Control Doc を参照。
これが私の解決策です:
フォームビルダーでフォームコントロールを初期化します:
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;
}
次に、determineId関数を作成してエクスポートします(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>
ライブデモの場合
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>
コンポーネントの主要部分(「変更」およびその他の詳細は省略):
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;
}
上記の「ngOnInit」の this.filter.setValue(this.selected)に注意してください。
Angular 6で動作するようです。
独自の比較機能を実装するだけです。
[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>
Typescriptファイル:
compareItems(i1, i2) {
return i1 && i2 && i1.id===i2.id;
}
これらの例のように私はそれをしました。 mat-selectの値をmat-optionsの1つの値に設定しようとしました。 しかし失敗した。
私の間違いは、[(value)] = "someNumberVariable"を数値型変数に対して実行し、mat-optionsのものは文字列でした。 テンプレートで同じに見えたとしても、そのオプションは選択されません。
someNumberVariableを文字列に解析すると、すべてが完全に問題ありませんでした。
したがって、mat-selectとmat-optionの値を同じ数にする必要があるようです(数値を表示している場合)だけでなく、文字列にすることもできます。
私の解決策は少しトリッキーでシンプルです。
<div>
<mat-select
[placeholder]="selected2">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
プレースホルダーを利用しました。 マテリアルプレースホルダーのデフォルトの色は「ライトグレー」です。 オプションが選択されているように見せるために、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>
< / mat-form-field>。
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
数値と文字列の比較はfalse を使用するため、選択した値をngOnInit内の文字列にキャストすると、機能します。
私も同じ問題を抱えていて、マットセレクションをエナムで満たしました。
Object.keys(MyAwesomeEnum).filter(k => !isNaN(Number(k)));
選択したいエニューム値がありました。..
それが機能しなかった理由を特定するために、私は数時間かけて心を悩ませました。 そして、マット選択、キーコレクション、および選択されたもので使用されているすべての変数をレンダリングした直後にそれを行いました。.. ["0"、 "1"、 "2"]があり、1(数値)を選択する場合 1 == "1"はfalseであり、そのため何も選択されません。。
したがって、 solution は、選択した値をngOnInit内の文字列にキャストすることであり、機能します。
デフォルト値のバインディングまたは設定は、 MatSelect の value 属性が MatOption にバインドされた value 属性に匹敵する場合にのみ機能します。 アイテムの「キャプション」を mat-option 要素の value 属性にバインドする場合は、アイテムの mat-select のデフォルト要素も「キャプション」に設定する必要があります。 アイテムの「Id」を mat-option にバインドする場合は、「id」を mat-select にもバインドする必要があります。アイテム全体、キャプションなどではなく、同じフィールドのみです。
しかし、バインディングでそれを行う必要があります[]。
私がやった。
<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 ===も選択したので、おそらく後者です。 ? 選択:オプション "
と機能しませんでした。