53 votes

Définir l'élément initialement sélectionné dans une liste de sélection dans Angular2

J'ai réussi à lier une Select list à mon modèle pour l'enregistrer, mais je n'arrive pas à trouver comment faire pour qu'Angular2 sélectionne automatiquement la bonne option sur la Select list si je fournis une fonctionnalité d'édition. En d'autres termes, si je modifie un objet préexistant via un formulaire, j'ai besoin que la liste Select reflète l'état initial de l'objet (par exemple l'option 5 dans la liste Select), plutôt que de sélectionner par défaut le premier élément.

<select [ngModel]="originalObject">
    <option *ngFor="let object of objects" [ngValue]="object">{{object.name}}</option>
</select>

Comment j'imagine que cela devrait fonctionner, mais ce n'est pas le cas !

<select [ngModel]="originalObject">
    <option *ngFor="let object of objects" [ngValue]="object" [selected]="object === originalObject">{{object.name}}</option>
</select>

J'essaie donc d'utiliser la propriété "selected" de l'option, mais pour une raison quelconque, cela ne fait rien. Le "selectedObject" dans ce cas serait un objet dans le composant qu'il peut lire.

1 votes

En selected est remplacée par la propriété originalObject . ngValue ne fonctionne qu'avec ngModel . Sans ngValue vous ne pouvez utiliser que des valeurs de type chaîne de caractères, et non des objets avec <option> . C'est pourquoi je pense qu'il est préférable de se débarrasser de [selected]=...

0 votes

Pour l'instant, je n'utilise pas le [selected]=.. C'est ainsi que j'ai pensé que cela devait fonctionner. Ce n'est pas le cas pour le moment, mais il ne sélectionne pas la bonne option au chargement.

62voto

user3452805 Points 908

Ok, j'ai compris quel était le problème, et l'approche que je crois qui fonctionne le mieux. Dans mon cas, parce que les deux objets n'étaient pas identiques d'un Javascript point de vue, que dans la mesure où elles ont partagé les mêmes valeurs, mais ils étaient différents objets réels, par exemple, originalObject a été instancié entièrement séparément objects qui était essentiellement un ensemble de données de référence (pour remplir la liste déroulante).

J'ai trouvé que l'approche qui fonctionne le mieux pour moi était de comparer une propriété unique des objets, plutôt que de comparer directement l'ensemble des deux objets. Cette comparaison est effectuée dans la limite de propriété selected:

<select [ngModel]="originalObject">
    <option *ngFor="let object of objects" [ngValue]="object" [selected]="object.uniqueId === originalObject.uniqueId">{{object.name}}</option>
</select>

3 votes

Cela fonctionne ! , you have to remove [ngModel]="originalObject" from the select statement : <select> <option *ngFor="let object of objects" [ngValue]="object" [selected]="object.uniqueId === originalObject.uniqueId">{{object.name}}</option> </select>

0 votes

L'important est que deux instances distinctes ayant exactement les mêmes propriétés ne correspondent pas, c'est-à-dire qu'elles sont récupérées par des appels d'API différents (ce qui était le cas pour moi). Il suffit alors de remplacer la propriété utilisée comme valeur par celle des options comme suit : myObj = this.options.filter(o => o.id === myObj.id)[0] ; Notez simplement qu'en modifiant l'objet, celui-ci sera également mis à jour dans la collection d'options.

56voto

mrebval Points 616

Mise à jour vers angular 4.X.X, il y a une nouvelle façon de marquer une option sélectionnée :

<select [compareWith]="byId" [(ngModel)]="selectedItem">
  <option *ngFor="let item of items" [ngValue]="item">{{item.name}}
  </option>
</select>

byId(item1: ItemModel, item2: ItemModel) {
  return item1.id === item2.id;
}

Certains tutoriel ici

5 votes

Il m'a fallu des heures pour trouver cette réponse. Elle m'a sauvé la mise.

1 votes

Il faut également ajouter l'attribut name pour l'élément select. Sinon, j'obtiens l'erreur suivante

0 votes

@yunuskula Il ne semble pas que l'attribut name soit nécessaire.

9voto

Günter Zöchbauer Points 21340

Si vous utilisez

<select [ngModel]="object">
    <option *ngFor="let object of objects" [ngValue]="object">{{object.name}}</option>
</select>

Vous devez définir la propriété object dans votre classe de composants à l'élément de objects que vous souhaitez présélectionner.

class MyComponent {
  object;
  objects = [{name: 'a'}, {name: 'b'}, {name: 'c'}];
  constructor() {
    this.object = this.objects[1];
  }
}

0 votes

Je m'excuse, je pense que j'ai accidentellement appelé deux objets object dans la question. J'ai modifié la question. Les originalObject y objects existent et contiennent des données. originalObject est essentiellement ce que doit être l'élément de liste sélectionné, et objects est le tableau des options possibles, dont l'une serait originalObject .

0 votes

Exemple d'un plongeur exactement comme dans ma réponse.

0 votes

Ah, je vois. Il semble que cela puisse être lié au fait qu'il s'agit d'une référence ? Si vous changez le code dans le Plunker en this.originalObject = {name: 'b'}; la liste de sélection ne sera plus par défaut b mais il prend par défaut le premier élément du tableau, a . Des idées à ce sujet ?

3voto

Jinu Points 71

Vous pouvez réaliser la même chose en utilisant

<select [ngModel]="object">
  <option *ngFor="let object of objects;let i= index;" [value]="object.value" selected="i==0">{{object.name}}</option>
</select>

0voto

AngJobs on Github Points 5111

Cela fonctionnera-t-il si l'on retire l'élément modifié du tableau et qu'on le place au début du tableau, de manière à ce qu'il soit automatiquement sélectionné ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X