Warum enthält AngularJS eine leere Option in select?

Ich habe in den letzten Wochen mit AngularJS gearbeitet, und die einzige Sache, die mich wirklich stört, ist, dass ich selbst alle Permutationen oder die Konfiguration, die in der Spezifikation unter http://docs.angularjs.org/api/ng definiert ist, ausprobiert habe .directive: select , ich erhalte immer noch eine leere Option als erstes Kind des select Elements.

Hier ist die Jade:

select.span9(ng-model='form.type', required, ng-options='option.value as option.name for option in typeOptions'); 

Hier der Controller:

 $scope.typeOptions = [ { name: 'Feature', value: 'feature' }, { name: 'Bug', value: 'bug' }, { name: 'Enhancement', value: 'enhancement' } ]; 

Schließlich ist hier der HTML-Code, der generiert wird:

   Feature Bug Enhancement  

Was muss ich tun, um es los zu werden?

PS: Es funktioniert auch ohne das, aber es sieht einfach komisch aus, wenn du select2 ohne Mehrfachselektion verwendest.

Solutions Collecting From Web of "Warum enthält AngularJS eine leere Option in select?"

Die leere option wird generiert, wenn ein von ng-model referenzierter Wert nicht in einer Reihe von Optionen enthalten ist, die an ng-options . Dies verhindert zufällige Modellauswahl: AngularJS kann sehen, dass das ursprüngliche Modell entweder nicht definiert ist oder nicht in der Menge der Optionen enthalten ist und nicht allein den Modellwert bestimmen möchte.

Wenn Sie die leere Option loswerden wollen, wählen Sie einfach einen Anfangswert in Ihrem Controller, etwa:

 $scope.form.type = $scope.typeOptions[0].value; 

Hier ist die jsFiddle: http://jsfiddle.net/MTfRD/3/

Kurz gesagt: die leere Option bedeutet, dass kein gültiges Modell ausgewählt ist (mit gültig ich meine: aus der Menge der Optionen). Sie müssen einen gültigen Modellwert auswählen, um diese leere Option zu entfernen.

Wenn Sie einen Anfangswert haben wollen, sehen Sie sich die Antwort von @ pkozlowski.opensource an, welche FYI auch mit ng-init in der View (und nicht im Controller) implementiert werden kann:

  

Wenn Sie keinen Anfangswert wünschen, kann “ein einzelnes fest codiertes Element mit dem Wert, der auf eine leere Zeichenfolge festgelegt ist, in das Element geschachtelt werden. Dieses Element stellt dann die Option null oder” nicht ausgewählt “dar”:

  

Eckig <1.4

Für alle da draußen, die “null” als gültigen Wert für eine der Optionen behandeln (also stellen Sie sich vor, dass “null” ein Wert eines der Elemente in typeOptions in Beispiel unten ist), fand ich den einfachsten Weg, um sicherzustellen, dass automatisch hinzugefügt Die Option ist ausgeblendet, um ng-if zu verwenden.

  

Warum ng-ob und nicht-verstecken? Da Sie css-Selektoren möchten, die die erste Option innerhalb von oben auswählen, wählen Sie die Option “reelle”, nicht die, die ausgeblendet ist. Es wird nützlich, wenn Sie angularmesser für E2e-Tests verwenden und (aus welchen Gründen auch immer) Sie by.css () verwenden, um ausgewählte Optionen zu targetieren.

angular> = 1.4

Aufgrund des Refactorings der Select- und Options-Direktiven ist die Verwendung von ng-if keine praktikable Option mehr, daher müssen Sie sich an ng-show="false" wenden, damit es wieder funktioniert.

Vielleicht nützlich für jemanden:

Wenn Sie einfache Optionen anstelle von ng-Optionen verwenden möchten, können Sie Folgendes tun:

  

Stellen Sie das Modell inline ein. Verwenden Sie ng-init, um die leere Option zu entfernen

Unter den vielen Antworten hier, dachte ich mir, ich würde die Lösung, die für mich funktionierte, umschreiben und alle folgenden Bedingungen erfüllen:

  • hat einen Platzhalter / eine Eingabeaufforderung bereitgestellt, wenn das ng-Modell falsch ist (zB “- Region auswählen -” w. value="" )
  • Wenn der ng-model-Wert falsch ist und der Benutzer das Optionsfeld öffnet, wird der Platzhalter ausgewählt (andere hier erwähnte Lösungen lassen die erste Option ausgewählt erscheinen, die irreführend sein kann)
  • Ermöglichen Sie dem Benutzer, einen gültigen Wert abzuwählen, indem Sie im Wesentlichen den Falsy / Default-Wert erneut auswählen

Bildbeschreibung hier eingeben

Code

  

src

original q & a – https://stackoverflow.com/a/32880941/1121919

Etwas ähnliches passierte mir auch und wurde durch ein Upgrade auf eckige 1.5 verursacht. ng-init scheint in neueren Versionen von Angular nach Typen geparst zu werden. In älteren ng-init="myModelName=600" würde ng-init="myModelName=600" einer Option mit dem Wert “600” zugeordnet werden, dh aber in Angular 1.5 wird es nicht so aussehen, wie es scheint erwartet, eine Option mit dem Wert 600 zu finden, dh . Angular würde dann einen zufälligen ersten Punkt einfügen:

  

Angular <1.2.x

  

Schräg> 1.2

  

Eine schnelle Lösung:

 select option:empty { display:none } 

Hoffe es hilft jemandem. Idealerweise sollte die gewählte Antwort der Ansatz sein, aber falls dies nicht möglich ist, sollte sie als Patch funktionieren.

Ja ng-model erzeugt einen leeren Optionswert, wenn die ng-model-Eigenschaft nicht definiert ist. Wir können dies vermeiden, wenn wir dem ng-Modell ein Objekt zuweisen

Beispiel

angularcodierung

 $scope.collections = [ { name: 'Feature', value: 'feature' }, { name: 'Bug', value: 'bug' }, { name: 'Enhancement', value: 'enhancement'} ]; $scope.selectedOption = $scope.collections[0];  

Wichtige Notiz:

Weisen Sie dem ng-model Objekt des Arrays wie $ scope.collections [0] oder $ scope.collections [1] zu, verwenden Sie keine Objekteigenschaften. Wenn Sie einen Optionswert vom Server erhalten, verwenden Sie die callbackfunktion und weisen Sie das Objekt ng-model zu

HINWEIS von eckigem Dokument

Hinweis: ngModel vergleicht nach Referenz, nicht nach Wert. Dies ist wichtig beim Binden an ein Array von Objekten. siehe ein Beispiel http://jsfiddle.net/qWzTb/

Ich habe viele Male versucht, es endlich zu finden.

Obwohl die Antworten von @ pkozlowski.opensource und @Mark korrekt sind, möchte ich meine leicht modifizierte Version teilen, wobei ich immer das erste Element in der Liste auswähle, unabhängig von seinem Wert:

  

Ich stand vor demselben Problem. Wenn Sie ein eckiges Formular mit normaler Post verfassen, werden Sie auf dieses Problem stoßen, da eckige es Ihnen nicht erlaubt, Werte für die Optionen in der Weise festzulegen, wie Sie sie verwendet haben. Wenn Sie den Wert von “form.type” erhalten, dann finden Sie den richtigen Wert. Sie müssen das eckige Objekt selbst, nicht das Formular, veröffentlichen.

Ok, eigentlich ist die Antwort ganz einfach: Wenn es eine Option gibt, die von Angular nicht erkannt wird, enthält sie eine langweilige. Was Sie falsch machen ist, wenn Sie ng-options verwenden, liest es ein Objekt, sagen wir [{ id: 10, name: test }, { id: 11, name: test2 }] right?

Dies ist, was Ihr Modellwert sein muss, um es als gleichwertig zu bewerten. Sagen Sie, dass der ausgewählte Wert 10 sein soll. Sie müssen Ihr Modell auf einen Wert wie { id: 10, name: test } , um 10 auszuwählen Erstellen Sie diesen Müll NICHT.

Ich hoffe, es hilft jedem zu verstehen, ich hatte eine harte Zeit, es zu versuchen 🙂

Ich verwende Angular 1.4x und habe dieses Beispiel gefunden, also habe ich ng-init verwendet, um den Anfangswert in der Auswahl zu setzen:

  

Eine einfache Lösung besteht darin, eine Option mit einem leeren Wert zu setzen. "" Ich habe festgestellt, dass dies die extra undefinierte Option eliminiert.

Das hat für mich funktioniert

  

Das funktioniert ganz gut

  

Die Art und Weise, wie es funktioniert, ist, dass dies die erste Option gibt, die vor der Auswahl von etwas und der display:none entfernt sie aus dem Dropdown, wenn Sie möchten, können Sie tun

  

und das wird Ihnen die select and option vor der Auswahl geben, aber einmal ausgewählt, wird es verschwinden, und es wird nicht in der Dropdownliste angezeigt.

Probieren Sie dieses in Ihrem Controller in der gleichen Reihenfolge aus:

 $scope.typeOptions = [ { name: 'Feature', value: 'feature' }, { name: 'Bug', value: 'bug' }, { name: 'Enhancement', value: 'enhancement' } ]; $scope.form.type = $scope.typeOptions[0]; 

Hier ist die Lösung:

für Beispieldaten wie:

 financeRef.pageCount = [{listCount:10,listName:modelStrings.COMMON_TEN_PAGE}, {listCount:25,listName:modelStrings.COMMON_TWENTYFIVE_PAGE}, {listCount:50,listName:modelStrings.COMMON_FIFTY_PAGE}]; 

Die Auswahloption sollte wie folgt aussehen:

  

Der Punkt, an dem wir value.listCount als value.listName schreiben, value.listCount automatisch den Text in value.listName aber der Wert der ausgewählten Option ist value.listCount obwohl die Werte meine normal value.listCount 0,1,2 .. und so weiter !!!

In meinem Fall greift das value.listCount tatsächlich auf value.listCount und ich kann meine Manipulation im Controller dynamisch durchführen.

Ich möchte hinzufügen, dass, wenn der Anfangswert von einer Bindung von einem Elternelement oder 1,5-Komponente stammt, stellen Sie sicher, dass der richtige Typ übergeben wird. Wenn @ in Bindung verwendet wird, wird die übergebene Variable string und wenn die Optionen sind z. Integer wird dann die leere Option angezeigt.

Entweder den Wert in init richtig parsen oder mit < und nicht mit @ binden (weniger empfohlen für die performance, wenn es nicht notwendig ist).

Einfache Lösung

  

Eine Grind-Lösung mit jQuery, wenn Sie nicht die Kontrolle über die Optionen haben

html:

  

js:

 $scope.init = function () { jQuery('#selector option:first').remove(); $scope.selector=jQuery('#selector option:first').val(); } 

Wenn Sie das Modell mit ng-init verwenden, um dieses Problem zu lösen:

  

Ich hatte das gleiche Problem, ich (entfernt “NG-Modell”) änderte dies:

  

zu diesem:

  

Jetzt funktioniert es, aber in meinem Fall war es so, dass ich den Bereich von ng.controller gelöscht habe, überprüfe, ob du nicht das gleiche getan hast.

Hi, ich hatte einige Referenzen von jQuery Mobile und habe sie entfernt. Mit jQuery Mobile funktionierte eine der obigen Fixes nicht für mich. (Es ist großartig, wenn jemand den Konflikt zwischen jQuery Mobile und Angular JS erklären kann)

https://guntucomputerhacks.blogspot.com.au/2017/10/angular-js-drop-down-first-options-vs.html

Das einzige, was mir geholfen hat, ist die Verwendung von track by In ng-options wie folgt:

   

Diese Lösung funktioniert für mich: