web-dev-qa-db-fra.com

Angularjs select ne marque pas le modèle correspondant comme sélectionné

J'ai un problème avec mon ngModel dans select qui ne s'affiche pas comme sélectionné. Id et name concordent mais ne fonctionnent pas, voir selectedState. Le modèle pointant vers l'objet réel dans le tableau d'options fonctionne, voir selelectedState2. Aucune idée de ce qui se passe ... 

Fiddle: http://jsfiddle.net/fedorsmirnoff/b49n4Ldp/2/

<select ng-model="selectedState" ng-options="state.name for state in stateOptions"></select>

<select ng-model="selectedState2" ng-options="state.name for state in stateOptions"></select>

function MainCtrl($scope) {
 $scope.stateOptions = [
     {id: 1, name: "Alaska"},
     {id: 2, name: "Montana"},
     {id: 3, name: "Nebraska"},
     {id: 4, name: "Texas"}
  ]

 $scope.selectedState = {id: 2, name: "Montana"};

 $scope.selectedState2 = $scope.stateOptions[1];

}
21
Micor

En effet, chaque objet a son propre $hashKey fourni par Angular que Angular utilise pour déterminer s'il est identique. Vous créez un nouvel objet (avec un $hashKey différent) sur $scope.selectedState. La manière dont vous le définissez sur $scope.selectedState2 est correcte.

Vous pouvez également utiliser track by pour faire en sorte que Angular suive state.id au lieu du $hashKey de l'objet:

<select ng-model="selectedState" ng-options="state.name for state in stateOptions track by state.id"></select>
31
m59

Si vous fournissez un objet en tant que modèle qui ne contient pas la référence à la liste existante, utilisez track by avec la valeur unique de votre modèle. Ainsi, au lieu d'utiliser la valeur unique unique $$ hashKey personnalisée, ng-options utilisera la propriété. que vous fournissez dans la piste pour suivre le modèle ng en cours de définition.

  ng-options="state.name for state in stateOptions track by state.id"

Démo

Non seulement il est utile pour définir ng-model sur n’importe quelle référence, mais il est également très efficace en termes de performances, en particulier lorsque votre liste est actualisée, les éléments ne sont ni supprimés ni recréés. élément.

Voici un très bon exemple pour cela .

8
PSL

Angular Team a signalé ce problème dans la documentation de ngSelect here :

Remarque: ngModel compare par référence et non par valeur. Ceci est important lors de la liaison à un tableau d'objets. Voir un exemple dans jsfiddle .

 $scope.options = [
    { label: 'one', value: 1 },
    { label: 'two', value: 2 }
  ];

  // Although this object has the same properties as the one in $scope.options,
  // Angular considers them different because it compares based on reference
  $scope.incorrectlySelected = { label: 'two', value: 2 };

  // Here we are referencing the same object, so Angular inits the select box correctly
  $scope.correctlySelected = $scope.options[1];
3
Dalorzo

Lorsque vous définissez $ scope.selectedState, vous créez en réalité un nouvel objet javascript, qui n'est pas un élément de $ scope.stateOptions. Par conséquent, l'élément select ne sélectionnerait pas l'élément correspondant dans $ scope.stateOptions.

Vous pouvez utiliser "suivi par" dans l'expression de sélection si vous devez sélectionner des éléments à l'aide d'une valeur attr unique. 

2
Tharaka

Essayez d'ajouter Track by state.id à la fin de votre déclaration ng-options.

1
Mindastic

Je pense que Angular utilise la vérification de référence au lieu de comparer deux objets ayant les mêmes propriétés. Dans votre cas, $ scope.selectedState2 renvoie un objet différent. J'utilise habituellement le sous-magasin pour trouver l'élément sélectionné dans un tableau pour l'initialisation.

0
Hung Nguyen