it-swarm.com.de

Warum enthält AngularJS eine leere Option in select?

Ich habe in den letzten Wochen mit AngularJS gearbeitet, und das einzige, was mich wirklich stört, ist, dass ich alle Permutationen oder die in der Spezifikation unter http://docs.angularjs.org) definierte Konfiguration ausprobiert habe /api/ng.directive:select , ich erhalte immer noch eine leere Option als erstes untergeordnetes Element von select.

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:

<select ng-model="form.type" required="required" ng-options="option.value as option.name for option in typeOptions" class="span9 ng-pristine ng-invalid ng-invalid-required">
    <option value="?" selected="selected"></option>
    <option value="0">Feature</option>
    <option value="1">Bug</option>
    <option value="2">Enhancement</option>
</select>

Was muss ich tun, um es loszuwerden?

P .: Ohne das geht es auch nicht, aber es sieht merkwürdig aus, wenn Sie select2 ohne Mehrfachauswahl verwenden.

635
Sudhanshu

Das leere option wird generiert, wenn ein Wert, auf den ng-model verweist, in einer Reihe von Optionen, die an ng-options übergeben wurden, nicht vorhanden ist. Dies geschieht, um eine versehentliche Modellauswahl zu verhindern: AngularJS kann erkennen, dass das ursprüngliche Modell entweder nicht definiert ist oder nicht in den Optionen enthalten ist, und möchte den Modellwert nicht selbst bestimmen.

Wenn Sie die leere Option entfernen möchten, wählen Sie einfach einen Anfangswert in Ihrem Controller aus.

$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" meine ich: aus dem Optionssatz). Sie müssen einen gültigen Modellwert auswählen, um diese leere Option zu entfernen.

635

Wenn Sie einen Anfangswert wünschen, lesen Sie die Antwort von @ pkozlowski.opensource, die Sie auch in der Ansicht (und nicht in der Steuerung) mit ng-init implementieren können:

<select ng-model="form.type" required="required" ng-init="form.type='bug'"
  ng-options="option.value as option.name for option in typeOptions" >
</select>

Wenn Sie keinen Anfangswert wünschen, kann "ein einzelnes fest codiertes Element mit dem Wert einer leeren Zeichenfolge in das Element geschachtelt werden. Dieses Element stellt dann die Option" Null "oder" Nicht ausgewählt "dar":

<select ng-model="form.type" required="required"
  ng-options="option.value as option.name for option in typeOptions" >
    <option style="display:none" value="">select a type</option>
</select>
228
Mark Rajcok

Angular <1.4

Für alle, die "null" als gültigen Wert für eine der Optionen behandeln (stellen Sie sich also vor, dass "null" ein Wert eines der Elemente in typeOptions ist. -) Im Beispiel unten) habe ich festgestellt, dass die Verwendung von ng-if der einfachste Weg ist, um sicherzustellen, dass die automatisch hinzugefügte Option ausgeblendet ist.

<select ng-options="option.value as option.name for option in typeOptions">
    <option value="" ng-if="false"></option>
</select>

Warum ng-if und nicht ng-hide? Weil Sie CSS-Selektoren wollen, die auf die erste Option innerhalb der obigen Liste abzielen, und nicht auf die Option, die versteckt ist. Dies ist nützlich, wenn Sie Winkelmesser für e2e-Tests verwenden und (aus welchen Gründen auch immer) by.css () verwenden, um ausgewählte Optionen auszuwählen.

Angular> = 1.4

Aufgrund der Überarbeitung der select- und options-Direktiven ist die Verwendung von ng-if nicht mehr möglich. Sie müssen sich also an ng-show="false" wenden, damit es wieder funktioniert.

120
WTK

Vielleicht nützlich für jemanden:

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

<select ng-model="sortorder" ng-init="sortorder='publish_date'">
  <option value="publish_date">Ascending</option>
  <option value="-publish_date">Descending</option>
</select>

Setzen Sie das Modell inline. Verwenden Sie ng-init, um leere Optionen zu entfernen

36

Ähnliches passierte auch mit mir und wurde durch ein Upgrade auf angular 1.5 ._ng-init_ verursacht, das in neueren Versionen von Angular nach type analysiert wurde. In älteren Angular _ng-init="myModelName=600"_ würde eine Option mit dem Wert "600" zugeordnet, dh _<option value="600">First</option>_, aber in Angular 1.5 wird dies nicht so gefunden, wie es scheint Erwarten Sie eine Option mit dem Wert 600, dh _<option value=600>First</option>_. Angular würde dann ein zufälliges erstes Element einfügen:

_<option value="? number:600 ?"></option>
_

Angular <1.2.x

_<select ng-model="myModelName" ng-init="myModelName=600">
  <option value="600">First</option>
  <option value="700">Second</option>
</select>
_

Angular> 1.2

_<select ng-model="myModelName" ng-init="myModelName='600'">
  <option value="600">First</option>
  <option value="700">Second</option>
</select>
_
21
Nabil Boag

Unter den vielen Antworten hier dachte ich, ich würde die für mich funktionierende Lösung erneut veröffentlichen und alle der folgenden Bedingungen erfüllen :

  • hat einen Platzhalter/Eingabeaufforderung bereitgestellt, wenn das ng-Modell falsch ist (zB "--select region--" w. value="")
  • wenn der ng-Modellwert falsch ist und der Benutzer das Options-Dropdown-Menü öffnet, wird der Platzhalter ausgewählt (andere hier erwähnte Lösungen lassen die erste Option als ausgewählt erscheinen, was irreführend sein kann).
  • ermöglichen Sie dem Benutzer, die Auswahl eines gültigen Werts aufzuheben, indem Sie im Wesentlichen den Wert falsy /default erneut auswählen

enter image description here

Code

<select name="market_vertical" ng-model="vc.viewData.market_vertical"
    ng-options="opt as (opt | capitalizeFirst) for opt in vc.adminData.regions">

    <option ng-selected="true" value="">select a market vertical</option>
</select>

src

original-Q & A - https://stackoverflow.com/a/32880941/1121919

20
jusopi

Eine schnelle Lösung:

select option:empty { display:none }

Hoffe es hilft jemandem. Im Idealfall sollte die ausgewählte Antwort der Ansatz sein, aber wenn dies nicht möglich ist, sollte dies als Patch funktionieren.

16
K K

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

Beispiel

winkelcodierung

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

$scope.selectedOption = $scope.collections[0];


<select class='form-control' data-ng-model='selectedOption' data-ng-options='item as item.name for item in collections'></select>

Wichtige Notiz:

Weisen Sie ng-model ein Array-Objekt wie $ scope.collections [0] oder $ scope.collections [1] zu. Verwenden Sie keine Objekteigenschaften. Wenn Sie mithilfe der Rückruffunktion einen Wert für die Auswahloption vom Server erhalten, weisen Sie das Objekt dem ng-Modell zu

HINWEIS aus Angular Dokument

Anmerkung: 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, endlich habe ich es gefunden.

14

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

<select ng-options="option.value as option.name for option in typeOptions" ng-init="form.type=typeOptions[0].value">
</select>
8
denkan

Ich verwende Angular 1.4x und habe dieses Beispiel gefunden. Daher habe ich ng-init verwendet, um den Anfangswert in der Auswahl festzulegen:

<select ng-init="foo = foo || items[0]" ng-model="foo" ng-options="item as item.id for item in items"></select>
3
James Drinkard

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

Dies ist, was Ihr Modellwert sein muss, um es als gleich zu bewerten. Angenommen, Sie möchten, dass der ausgewählte Wert 10 ist. Sie müssen Ihr Modell auf einen Wert wie { id: 10, name: test } einstellen, um 10 auszuwählen. Daher wird dieser Papierkorb NICHT erstellt .

Hoffe, es hilft allen zu verstehen, ich hatte eine harte Zeit zu versuchen :)

3
Marco


Ich stand vor dem gleichen Problem. Wenn Sie ein angular Formular mit normalem Beitrag posten, tritt dieses Problem auf, da Sie mit angular keine Werte für die Optionen festlegen können, wie Sie sie verwendet haben. Wenn Sie den Wert "form.type" erhalten, finden Sie den richtigen Wert. Sie müssen das angular Objekt selbst posten, nicht das Formular posten.

3
Jitu

Eine einfache Lösung besteht darin, eine Option mit einem leeren Wert festzulegen. _""_ Ich habe festgestellt, dass dadurch die zusätzliche undefinierte Option entfernt wird.

2
kgrondell

Das funktioniert einwandfrei

<select ng-model="contact.Title" ng-options="co for co in['Mr.','Ms.','Mrs.','Dr.','Prof.']">
    <option style="display:none" value=""></option>
</select>

so funktioniert es, dass die erste Option angezeigt wird, bevor etwas ausgewählt wird, und der display:none sie aus dem Dropdown-Menü entfernt, damit Sie dies tun können, wenn Sie dies möchten

<select ng-model="contact.Title" ng-options="co for co in['Mr.','Ms.','Mrs.','Dr.','Prof.']">
    <option style="display:none" value="">select an option...</option>
</select>

und dies gibt Ihnen den select and option vor der Auswahl, aber sobald es ausgewählt ist, verschwindet es und wird nicht in der Dropdown-Liste angezeigt.

1
David Genger

Diese Lösung funktioniert bei mir:

<select ng-model="mymodel">    
   <option ng-value="''" style="display:none;" selected>Country</option>
   <option value="US">USA</option>
</select>
1
MMM

Das hat bei mir funktioniert

<select ng-init="basicProfile.casteId" ng-model="basicProfile.casteId" class="form-control">
     <option value="0">Select Caste....</option>
     <option data-ng-repeat="option in formCastes" value="{{option.id}}">{{option.casteName}}</option>
 </select>
1

Wir können CSS verwenden, um die erste Option auszublenden. Dies funktioniert jedoch in IE 10, 11 nicht. Der beste Weg ist, das Element mit Jquery zu entfernen. Diese Lösung funktioniert für große Browser, die in chrome und IE10, 11 getestet wurden

Auch wenn Sie angular verwenden, funktioniert manchmal die Verwendung von setTimeout

$scope.RemoveFirstOptionElement = function (element) {
    setTimeout(function () {
        $(element.children()[0]).remove();
    }, 0);
};
0
Ashok Kumar

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

html:

<select id="selector" ng-select="selector" data-ng-init=init() >
...
</select>

js:

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

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

<select ng-model="foo" ng-app ng-init="foo='2'">
0
Pauly Garcia

Hallo, ich hatte einige jQUery-Handynummern und habe sie entfernt. Mit jQuery Mobile funktionierte eine der oben genannten Korrekturen bei mir nicht. (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

Hier ist das Update:

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 folgendermaßen aussehen: -

<select ng-model="financeRef.financeLimit" ng-change="financeRef.updateRecords(1)" 
class="perPageCount" ng-show="financeRef.showTable" ng-init="financeRef.financeLimit=10"
ng-options="value.listCount as value.listName for  value in financeRef.pageCount"
></select>

Wenn wir value.listCount als value.listName schreiben, wird der Text automatisch in value.listName eingefügt, aber der Wert der ausgewählten Option ist value.listCount, obwohl die Werte my normal 0 anzeigen. 1,2 .. und so weiter !!!

In meinem Fall greift der financeRef.financeLimit tatsächlich nach dem value.listCount und ich kann meine Manipulation im Controller dynamisch durchführen.

0
lisapanda

Versuchen Sie dies in Ihrem Controller in der gleichen Reihenfolge:

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

Einfache lösung

<select ng-model='form.type' required><options>
<option ng-repeat="tp in typeOptions" ng-selected="    
{{form.type==tp.value?true:false}}" value="{{tp.value}}">{{tp.name}}</option>
0
gajendra kumar

Das einzige, was für mich funktioniert hat, ist die Verwendung von track by in ng-options, wie folgt:

 <select class="dropdown" ng-model="selectedUserTable" ng-options="option.Id as option.Name for option in userTables track by option.Id">
0
Dipendu Paul

ich hatte das gleiche Problem, ich (entfernt "ng-Modell") änderte dies:

<select ng-model="mapayear" id="mapayear" name="mapayear" style="  display:inline-block !important;  max-width: 20%;" class="form-control">
  <option id="removable" hidden> Selecione u </option>
    <option selected ng-repeat="x in anos" value="{{ x.ano }}">{{ x.ano }}
</option>
</select>

dazu:

<select id="mapayear" name="mapayear" style="  display:inline-block !important;  max-width: 20%;" class="form-control">
  <option id="removable" hidden> Selecione u </option>
    <option selected ng-repeat="x in anos" value="{{ x.ano }}">{{ x.ano }}
</option>
</select>

jetzt funktioniert es, aber in meinem Fall wurde dieser Bereich von ng.controller gelöscht. Überprüfen Sie, ob Sie nicht dasselbe getan haben.

0
Kuza Grave

Ich möchte hinzufügen, dass, wenn der Anfangswert aus einer Bindung eines übergeordneten Elements oder einer 1.5-Komponente stammt, sichergestellt wird, dass der richtige Typ übergeben wird. Wenn beim Binden @ verwendet wird, ist die übergebene Variable ein String, und wenn die Optionen z. Ganzzahlen, dann wird die leere Option angezeigt.

Analysieren Sie entweder den Wert in init richtig oder binden Sie ihn mit < und nicht mit @ (für die Leistung wird weniger empfohlen, sofern dies nicht erforderlich ist).

0
Wtower

Sehen Sie sich das Beispiel aus der Dokumentation von anglejs an, um diese Probleme zu beheben.

  1. Gehen Sie zu diesem Dokumentationslink hier
  2. Suchen Sie nach ' Binding select an einen Nicht-String-Wert über ngModel-Parsing/-Formatierung '
  3. Dort können Sie sehen, dass die Direktive ' convertToNumber ' das Problem löst.

Für mich geht das. Kann auch sehen, wie es funktioniert hier

0
ihsanberahim