Pregunta ¿Por qué AngularJS incluye una opción vacía en select?


He estado trabajando con AngularJS durante las últimas semanas, y la única cosa que realmente me molesta es que incluso después de probar todas las permutaciones o la configuración definida en la especificación en http://docs.angularjs.org/api/ng.directive:select, Todavía recibo una opción vacía como primer hijo del elemento seleccionado.

Aquí está el Jade:

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

Aquí el controlador:

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

Finalmente, aquí está el HTML que se genera:

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

¿Qué debo hacer para deshacerme de él?

P.S .: Las cosas funcionan sin esto también, pero parece extraño si usas select2 sin selección múltiple.


604
2017-09-29 17:04


origen


Respuestas:


El vacío option se genera cuando un valor referenciado por ng-model no existe en un conjunto de opciones pasadas a ng-options. Esto sucede para evitar la selección accidental del modelo: AngularJS puede ver que el modelo inicial no está definido o no en el conjunto de opciones y no desea decidir el valor del modelo por sí mismo.

Si desea deshacerse de la opción vacía, simplemente seleccione un valor inicial en su controlador, algo como:

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

Aquí está el jsFiddle: http://jsfiddle.net/MTfRD/3/

En resumen: la opción vacía significa que no se selecciona ningún modelo válido (por válido quiero decir: del conjunto de opciones). Debe seleccionar un valor de modelo válido para deshacerse de esta opción vacía.


610
2017-09-29 17:26



Si desea un valor inicial, consulte la respuesta de @ pkozlowski.opensource, que FYI también se puede implementar en la vista (en lugar de en el controlador) usando 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 no desea un valor inicial, "un solo elemento codificado, con el valor establecido en una cadena vacía, puede anidarse en el elemento. Este elemento representará la opción nula o" no seleccionada "":

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

217
2017-12-10 21:09



Angular <1.4

Para cualquiera que trate "nulo" como valor válido para una de las opciones (así que imagine que "nulo" es el valor de uno de los elementos en typeOptions en el ejemplo a continuación), encontré que la forma más simple de asegurarse de que la opción agregada automáticamente esté oculta es usar ng-if.

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

Por qué ng-if y no ng-hide? Como quiere selectores de css que apuntarán a la primera opción en el interior, seleccione para seleccionar la opción "real", no la que está oculta. Se vuelve útil cuando estás usando transportador para pruebas e2e y (por cualquier razón) usas by.css () para seleccionar opciones de destino.

Angular> = 1.4

Debido a la refactorización de las directivas de selección y opciones, ng-if ya no es una opción viable, así que tienes que recurrir a ng-show="false" para hacer que funcione de nuevo.


115
2018-06-20 06:48



Tal vez sea útil para alguien:

Si desea utilizar opciones simples en lugar de ng-options, puede hacer lo siguiente:

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

Establecer el modelo en línea. Use ng-init para deshacerse de la opción vacía


36
2017-08-28 13:32



Entre la multitud de respuestas aquí, pensé que volvería a publicar la solución que funcionó para mí y conocí todas de las siguientes condiciones:

  • proporcionado un marcador de posición / prompt cuando el ng-modelo es falsy (por ejemplo, "--seleccionar región--" w. value="")
  • cuando el valor ng-model es falsy y el usuario abre el menú desplegable de opciones, se selecciona el marcador de posición (otras soluciones mencionadas aquí hacen que la primera opción aparezca seleccionada y puede ser engañosa)
  • permitir al usuario deseleccionar un valor válido, esencialmente seleccionando el falsy/ valor predeterminado de nuevo

enter image description here

código

<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

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


20
2018-04-27 14:53



Algo similar me estaba pasando a mí también y fue causado por una actualización a angular 1.5.ng-init parece estar siendo analizado por tipo en versiones más nuevas de Angular. En Angular más viejo ng-init="myModelName=600" se asignaría a una opción con el valor "600", es decir <option value="600">First</option> pero en Angular 1.5 no encontrará esto, ya que parece estar esperando encontrar una opción con valor 600 i.e <option value=600>First</option>. Angular luego insertaría un primer elemento aleatorio:

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

19
2018-03-17 14:47



Una solución rápida:

select option:empty { display:none }

Espero que ayude a alguien. Idealmente, la respuesta seleccionada debería ser el enfoque, pero si en caso de que eso no fuera posible, entonces debería funcionar como un parche.


15
2018-02-27 19:41



Sí ng-model creará un valor de opción vacío, cuando la propiedad ng-model no esté definida. Podemos evitar esto, si asignamos objeto a ng-model

Ejemplo

codificación angular

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

Nota IMPORTANTE:

Asigne el objeto de la matriz como $ scope.collections [0] o $ scope.collections [1] a ng-model, no use las propiedades del objeto. si obtiene el valor de opción de selección del servidor, usando la función de devolución de llamada, asigne el objeto al ng-model

NOTA del documento angular

Nota: ngModel se compara por referencia, no por valor. Esto es importante cuando se vincula a una matriz de objetos. ver un ejemplo http://jsfiddle.net/qWzTb/

Lo he intentado muchas veces, finalmente lo encontré.


13
2017-07-16 16:47



Aunque las respuestas de @pkozlowski.opensource y @ Mark son correctas, me gustaría compartir mi versión ligeramente modificada donde siempre selecciono el primer elemento de la lista, independientemente de su valor:

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

8
2018-06-11 18:02