Pourquoi AngularJS inclut une option vide dans select?

J'ai travaillé avec AngularJS ces dernières semaines, et la seule chose qui me dérange vraiment est que même après avoir essayé toutes les permutations ou la configuration définie dans la spécification à http://docs.angularjs.org/api/ng.directive:select , j'ai toujours une option vide comme premier enfant de l'élément select.

voici le Jade:

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

ici le contrôleur:

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

enfin, voici le HTML qui est généré:

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

Que dois-je faire pour m'en débarrasser?

P. S.: les Choses fonctionnent sans cela, mais il semble juste bizarre si vous utilisez select2 sans sélection multiple.

610
demandé sur Peter Mortensen 2012-09-29 21:04:45

25 réponses

la valeur vide option est générée lorsqu'une valeur référencée par ng-model n'existe pas dans un ensemble d'options passées à ng-options . Cela empêche la sélection accidentelle du modèle: AngularJS peut voir que le modèle initial n'est pas défini ou ne fait pas partie de l'ensemble des options et ne veut pas décider de la valeur du modèle tout seul.

Si vous voulez vous débarrasser de l'option " vide il suffit de sélectionner une valeur initiale dans votre contrôleur, quelque chose comme:

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

voici le jsFiddle: http://jsfiddle.net/MTfRD/3/

en bref: l'option vide signifie qu'aucun modèle valide n'est sélectionné (par valide je veux dire: de l'ensemble des options). Vous devez sélectionner une valeur de modèle valide pour vous débarrasser de cette option vide.

615
répondu pkozlowski.opensource 2012-09-29 17:54:07

Si vous voulez une valeur initiale, voir @pkozlowski.réponse d'opensource, que FYI peut aussi être implémenté dans la vue (plutôt que dans le contrôleur) en utilisant ng-init:

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

si vous ne voulez pas de valeur initiale, "un seul élément codé dur, avec la valeur définie à une chaîne vide, peut être imbriqué dans l'élément. Cet élément représentera alors l'option "null" ou" not selected":

<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>
222
répondu Mark Rajcok 2012-12-10 21:09:14

Angulaire < 1.4

pour quiconque traite" null "comme valeur valide pour l'une des options (donc imaginez que" null "est une valeur d'un des éléments dans typoeoptions dans l'exemple ci-dessous), j'ai trouvé que la façon la plus simple de s'assurer que l'option automatiquement ajoutée est cachée est d'utiliser ng-if.

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

pourquoi ng-if et non ng-hide? Parce que vous voulez des sélecteurs css qui ciblerait la première option à l'intérieur ci-dessus sélectionnez de cibler l'option "réel", pas celle qui est cachée. Il devient utile lorsque vous utilisez protractor pour le test e2e et (pour quelque raison que ce soit) vous utilisez par.(css) à la cible, sélectionnez options.

angulaire > = 1,4

en raison du remaniement des directives select et options, l'utilisation de ng-if n'est plus une option viable, vous devez donc vous tourner vers ng-show="false" pour que cela fonctionne à nouveau.

115
répondu WTK 2016-03-13 11:35:46

peut-être utile pour quelqu'un:

si vous voulez utiliser des options simples au lieu de ng-options, vous pouvez faire comme ci-dessous:

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

mettre le modèle en ligne. Utiliser ng-init pour se débarrasser de l'option vide

36
répondu Abraham Jagadeesh 2013-10-16 13:03:34

parmi les multitudes de réponses ici, j'ai pensé que je repousse la solution qui a fonctionné pour moi et a rencontré tous des conditions suivantes:

  • fournit un placeholder/prompt lorsque le modèle ng est falsy (e.g. "--select region-- " W. value="" )
  • lorsque la valeur du modèle ng est falsy et que l'utilisateur ouvre les options dropdown, le le paramètre est sélectionné (les autres solutions mentionnées ici font apparaître la première option sélectionnée qui peut être trompeuse)
  • permet à l'utilisateur de désélectionner une valeur valide, en sélectionnant essentiellement la falsy / valeur par défaut à nouveau

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&R - https://stackoverflow.com/a/32880941/1121919

20
répondu jusopi 2017-05-23 10:31:39

quelque chose de semblable m'est arrivé aussi et a été causé par une mise à niveau à l'angle 1.5. ng-init semble être interprété pour type dans les nouvelles versions D'Angular. Dans l'Ancien angle ng-init="myModelName=600" serait la carte à une option avec la valeur" 600 "i.e. <option value="600">First</option> mais dans L'angle 1.5 il ne trouvera pas cela car il semble s'attendre à trouver une option avec la valeur 600 I. e <option value=600>First</option> . Angular insérerait alors un premier élément aléatoire:

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

Angulaire < 1.2.x

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

angulaire > 1,2

<select ng-model="myModelName" ng-init="myModelName='600'">
  <option value="600">First</option>
  <option value="700">Second</option>
</select>
19
répondu Nabil Boag 2016-03-17 14:47:01

une solution rapide:

select option:empty { display:none }

J'espère que ça aidera quelqu'un. Idéalement, la réponse choisie devrait être l'approche mais si dans le cas où ce n'est pas possible alors devrait fonctionner comme un patch.

15
répondu K K 2016-10-27 14:14:07

Oui ng-modèle permettra de créer des vides valeur de l'option, lors de la ng-modèle bien défini. Nous pouvons éviter cela, si nous assignons objet à ng-model

exemple

angulaire de codage

$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>

Note Importante:

assigner un objet de tableau comme $scope.recouvrement[0] ou $ scope.collections[1] ng-model, ne pas utiliser les propriétés de l'objet. si vous obtenez la valeur de l'option select du serveur, en utilisant call back fonction, assigner objet à ng-model

NOTE du document angulaire

Note: ngModel compare par référence, et non par valeur. Ceci est important lorsque vous vous liez à un tableau d'objets. voir l'exemple http://jsfiddle.net/qWzTb /

j'ai essayé beaucoup de fois, enfin je l'ai trouvé.

13
répondu Kanagaraj Vadivel 2014-09-16 18:22:29

bien que tous les deux @pkozlowski.les réponses d'opensource et de @Mark sont correctes, j'aimerais partager ma version légèrement modifiée où je sélectionne toujours le premier élément de la liste, quelle que soit sa valeur:

<select ng-options="option.value as option.name for option in typeOptions" ng-init="form.type=typeOptions[0].value">
</select>
8
répondu denkan 2014-06-11 18:02:11



J'ai fait face à la même question. Si vous postez une forme angulaire avec un poteau normal, alors vous allez faire face à cette question, car angulaire ne vous permet pas de définir des valeurs pour les options de la façon dont vous avez utilisé. Si vous obtenez la valeur de ".tapez" alors vous allez trouver la bonne valeur. Vous devez poster l'objet angulaire qu'il se pas la forme post.

3
répondu Jitu 2013-02-03 11:13:23

Ok, en fait la réponse est très simple: quand il y a une option non reconnue par Angular, elle inclut une option terne. Ce que vous faites de mal est, lorsque vous utilisez ng-options, il lit un objet, dites [{ id: 10, name: test }, { id: 11, name: test2 }] right?

C'est ce que votre valeur de modèle doit être pour l'évaluer comme égale, disons que vous voulez que la valeur sélectionnée soit 10, vous devez définir votre modèle à une valeur comme { id: 10, name: test } pour sélectionner 10, donc il ne va pas créer cette corbeille.

J'espère aide tout le monde à comprendre, j'ai eu un moment difficile essayer :)

3
répondu Marco 2016-09-19 20:32:00

j'utilise L'angle 1,4 x et j'ai trouvé cet exemple, donc j'ai utilisé ng-init pour définir la valeur initiale dans le select:

<select ng-init="foo = foo || items[0]" ng-model="foo" ng-options="item as item.id for item in items"></select>
3
répondu James Drinkard 2017-05-18 18:14:29

une solution simple est de définir une option avec une valeur vide "" j'ai trouvé que cela élimine l'option non définie supplémentaire.

2
répondu kgrondell 2015-02-26 19:09:57

cela a fonctionné pour moi

<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
répondu Nayas Subramanian 2015-12-15 15:56:49

cela fonctionne parfaitement bien

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

la façon dont il fonctionne est, que cela donne la première option à afficher avant de sélectionner quelque chose et le display:none le supprime de la liste déroulante donc si vous voulez, vous pouvez faire

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

et cela vous donnera le select and option avant de sélectionner mais une fois sélectionné il disparaîtra, et il n'apparaîtra pas dans la liste déroulante.

1
répondu David Genger 2016-01-12 16:06:42

essayez celui - ci dans votre controller, dans le même ordre:

$scope.typeOptions = [
    { name: 'Feature', value: 'feature' }, 
    { name: 'Bug', value: 'bug' }, 
    { name: 'Enhancement', value: 'enhancement' }
];
$scope.form.type = $scope.typeOptions[0];
0
répondu Macfer Ann 2014-06-25 07:54:55

Voici Le fix:

pour un échantillon de données comme :

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

l'option select doit être comme ceci: -

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

le point étant quand nous écrivons value.listCount comme value.listName , il popule automatiquement le texte dans value.listName mais la valeur de l'option choisie est value.listCount bien que les valeurs que je montre normal 0,1,2 .. et ainsi de suite !!!

Dans mon cas, le financeRef.financeLimit est je prends le value.listCount et je peux faire ma manipulation dans le contrôleur dynamiquement.

0
répondu lisapanda 2014-09-03 18:55:00

je voudrais ajouter que si la valeur initiale provient d'une liaison d'un élément parent ou d'un composant 1.5, assurez-vous que le type approprié est passé. Si vous utilisez @ dans binding, la variable passée sera string et si les options sont par exemple. les entiers alors l'option vide apparaîtra.

analyser correctement la valeur init, ou lier avec < et non @ (moins recommandé pour la performance sauf si nécessaire).

0
répondu Wtower 2016-12-20 16:49:51

solution Simple

<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
répondu gajendra kumar 2017-01-28 14:26:06

une solution de mouture avec jQuery quand vous n'avez pas le contrôle des options

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
répondu Pascal KOCH 2017-04-05 13:23:50

Si vous utilisez ng-init votre modèle pour résoudre ce problème:

<select ng-model="foo" ng-app ng-init="foo='2'">
0
répondu Pauly Garcia 2017-08-23 19:05:11

j'ai eu le même problème, j' (supprimé "ng-model") a changé :

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

à ceci:

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

maintenant son fonctionnement, mais dans mon cas, il a été car j'ai supprimé cette portée de ng.contrôleur, vérifiez si vous n'avez pas fait la même chose.

0
répondu Kuza Grave 2017-09-13 08:52:02

Salut j'ai eu quelques références mobiles jQUery et je les ai enlevées. Avec jQuery mobile l'une des corrections ci-dessus ne fonctionnait pas pour moi. ( Son grand, si quelqu'un peut expliquer le conflit entre jQuery Mobile et Angular JS )

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

0
répondu Dulanjana Wickramatantri 2017-10-16 02:56:49

la seule chose qui a fonctionné pour moi est d'utiliser track by dans ng-options , comme ceci:

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

0
répondu Dipendu Paul 2017-11-19 19:30:51

Cette solution fonctionne pour moi:

<select ng-model="mymodel">    
   <option ng-value="''" style="display:none;" selected>Country</option>
   <option value="US">USA</option>
</select>
-1
répondu MMM 2018-07-12 11:04:17