J'ai un tapis de sélection où les options sont tous les objets définis dans un tableau. J'essaie de définir la valeur par défaut sur l'une des options, mais cette option est laissée sélectionnée lors du rendu de la page.
Mon fichier TypeScript contient:
public options2 = [
{"id": 1, "name": "a"},
{"id": 2, "name": "b"}
]
public selected2 = this.options2[1].id;
Mon fichier HTML contient:
<div>
<mat-select
[(value)]="selected2">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
J'ai essayé de définir selected2
et la value
dans mat-option
à la fois pour l'objet et son identifiant, et j'ai essayé d'utiliser à la fois [(value)]
et [(ngModel)]
dans mat-select
, mais aucun ne fonctionne.
J'utilise la version matérielle 2.0.0-beta.10
Merci
Utilisez une liaison pour la valeur dans votre modèle.
value="{{ option.id }}"
devrait être
[value]="option.id"
Et dans la valeur que vous avez sélectionnée, utilisez ngModel
au lieu de value
.
<mat-select [(value)]="selected2">
devrait être
<mat-select [(ngModel)]="selected2">
Code complet:
<div>
<mat-select [(ngModel)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">{{ option.name }}</mat-option>
</mat-select>
</div>
Remarque: à partir de version 2.0.0-beta.12 le sélection de matériel accepte maintenant un élément mat-form-field
comme élément parent, de sorte qu'il soit cohérent avec les autres contrôles d'entrée de matériau. Remplacez l'élément div
par l'élément mat-form-field
après la mise à niveau.
<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>
Utilisez compareWith
, une fonction pour comparer les valeurs d’option aux valeurs sélectionnées. voir ici: https://material.angular.io/components/select/api#MatSelect
Pour un objet de la structure suivante:
listOfObjs = [{ name: 'john', id: '1'}, { name: 'jimmy', id: '2'},...]
Définissez le balisage comme ceci:
<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>
Et définissez la fonction de comparaison comme ceci:
compareObjects(o1: any, o2: any): boolean {
return o1.name === o2.name && o1.id === o2.id;
}
J'utilise des formes angulaires 5 et réactives avec mat-select et je ne peux obtenir aucune des solutions ci-dessus pour afficher la valeur initiale.
J'ai dû ajouter [compareWith] pour traiter les différents types utilisés dans le composant mat-select. En interne, il semble que mat-select utilise un tableau pour contenir la valeur sélectionnée. Cela permettra probablement au même code de fonctionner avec plusieurs sélections si ce mode est activé.
Voici ma solution:
Form Builder pour initialiser le contrôle de formulaire:
this.formGroup = this.fb.group({
country: new FormControl([ this.myRecord.country.id ] ),
...
});
Puis implémentez la fonction compareWith sur votre composant:
compareIds(id1: any, id2: any): boolean {
const a1 = determineId(id1);
const a2 = determineId(id2);
return a1 === a2;
}
Créez et exportez ensuite la fonction DetermineI (je devais créer une fonction autonome pour que mat-select puisse l’utiliser):
export function determineId(id: any): string {
if (id.constructor.name === 'array' && id.length > 0) {
return '' + id[0];
}
return '' + id;
}
Enfin, ajoutez l’attribut compareWith à votre sélection de tapis:
<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>
Vous devriez le lier en tant que [value]
dans le mat-option
comme ci-dessous,
<mat-select placeholder="Panel color" [(value)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">
{{ option.name }}
</mat-option>
</mat-select>
Ma solution est peu compliquée et plus simple.
<div>
<mat-select
[placeholder]="selected2">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
Je viens d'utiliser le espace réservé . La couleur par défaut de l'espace réservé au matériau est light gray
. Pour donner l’impression que l’option est sélectionnée, je viens de manipuler le CSS comme suit:
::ng-deep .mat-select-placeholder {
color: black;
}
Comme déjà mentionné dans Angular 6, utiliser ngModel sous des formes réactives est déconseillé (et supprimé dans Angular 7). J'ai donc modifié le modèle et le composant comme suit.
Le gabarit:
<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>
Les parties principales du composant (onChanges
et d’autres détails sont omis):
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;
}
Remarque this.filter.setValue (this.selected) in ngOnInit
ci-dessus.
Cela semble fonctionner dans Angular 6.
La solution pour moi était:
<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);
});
Utilisation de l'objet: {id: number, detalle: string}
Essaye ça!
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
Je l'ai fait comme dans ces exemples. J'ai essayé de définir la valeur de la sélection de tapis sur la valeur de l'une des options de tapis. Mais a échoué.
Mon erreur a été de faire [(value)] = "someNumberVariable" à une variable de type numérique alors que celles de mat-options étaient des chaînes. Même s'ils avaient le même aspect dans le modèle, cette option ne serait pas sélectionnée.
Une fois, j’ai analysé le someNumberVariable en une chaîne, tout était parfait.
Il semble donc que vous ayez besoin que les valeurs mat-select et mat-option soient non seulement le même nombre (si vous présentez des nombres), mais que vous les laissiez être de type string.
Vous pouvez simplement implémenter votre propre fonction de comparaison
[compareWith]="compareItems"
Voir aussi le docu . Donc le code complet ressemblerait à ceci:
<div>
<mat-select
[(value)]="selected2" [compareWith]="compareItems">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
et dans le fichier TypeScript:
compareItems(i1, i2) {
return i1 && i2 && i1.id===i2.id;
}