21

Ich habe ein Problem mit meinem ngModel in Auswahl nicht angezeigt wie ausgewählt. Die ID und der Name stimmen überein, funktionieren aber nicht, siehe selectedState. Das Zeigen des Modells auf das tatsächliche Objekt innerhalb des Options-Arrays funktioniert, siehe selectedState2. Keine Ahnung, was los ist ...Angularjs Select markiert kein passendes Modell wie ausgewählt

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]; 

} 

Antwort

30

Dies liegt daran, jedes Objekt hat seine eigenen $hashKey ist von Angular vorgesehen, dass Angular verwendet, um zu bestimmen, ob sie gleich sind. Sie erstellen ein neues Objekt (mit einem anderen $hashKey) unter $scope.selectedState. Die Art, wie Sie es auf $scope.selectedState2 setzen, ist korrekt.

Sie können auch track by verwenden, um Schrägspur durch state.id anstelle des Objekt $hashKey zu machen:

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

Wenn Sie $ scope.selectedState gesetzt, führen Sie ein neues Javascript-Objekt tatsächlich zu schaffen, die nicht ein Element ist, der $ scope.stateOptions. Daher würde das select-Element nicht das entsprechende Element aus $ scope.stateOptions auswählen.

Sie können im Select-Ausdruck "track by" verwenden, wenn Sie Elemente mit einem eindeutigen attr-Wert auswählen müssen.

1

Versuchen Sie, Track von state.id am Ende Ihrer ng-Optionen-Anweisung hinzuzufügen.

3

Angular-Team erklärt dieses Problem in der Dokumentation zu ngSelect here:

Hinweis: ngModel vergleicht Bezug genommen wird, nicht Wert. Dies ist wichtig beim Binden an ein Array von Objekten. Siehe ein Beispiel in dieser 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]; 
+0

Das ist nicht ganz korrekt, je nachdem, wie ng-Option funktioniert, können Sie immer nach etwas verfolgen und das Modell mit diesem Eigenschaftswert setzen.Eine andere Möglichkeit wäre, den Wert als Wert für die Syntax zu verwenden. Sie können nicht immer wissen, zu welchem ​​Index ausgewählte Elemente in einem Array gehören (es sei denn, Sie durchlaufen eine sehr uneffiziente Übereinstimmung) – PSL

+0

@PSL schlagen Sie vor, dass eckiges Team falsch ist? – Dalorzo

+0

@PSL dies basiert auf Angular Team Dokumentation, wenn es unvollständig ist Angular Team auch den gleichen Fehler gemacht. – Dalorzo

8

Wenn Sie ein Objekt als Modell zur Verfügung stellen, die nicht den Verweis auf die bestehende Liste nicht halten, dann verwenden track by mit dem einzigartigen Wert des Modells, so dass statt den benutzerdefinierten einzigartigen $$ mit hashKey, ng-options verwendet die Eigenschaft, die Sie in der Spur angeben, indem Sie das ng-Modell verfolgen, das gesetzt wird.

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

Demo

Nicht nur, dass es in Einstellung ng-Modell auf jede Referenz nützlich ist, aber es hat auch ein hohes Maß an Leistung Wirksamkeit als auch vor allem, wenn Ihre Liste aktualisiert wird, werden die Elemente wird nicht entfernt und neu erstellt, sondern eckig aktualisiert nur das vorhandene Element.

Hier ist ein very good example for this.

0

Ich denke, Angular verwendet die Referenzprüfung, anstatt zwei Objekte mit denselben Eigenschaften zu vergleichen. In Ihrem Fall gibt $ scope.selectedState2 ein anderes Objekt zurück. Normalerweise verwende ich Understore, um das ausgewählte Element aus einem Array zur Initialisierung zu finden.

Verwandte Themen