Cómo tener una opción predeterminada en el cuadro de selección Angular.js

311

He buscado en Google y no puedo encontrar nada al respecto.

Tengo este codigo

<select ng-model="somethingHere" 
        ng-options="option.value as option.name for option in options"
></select>

Con algunos datos como este

options = [{
   name: 'Something Cool',
   value: 'something-cool-value'
}, {
   name: 'Something Else',
   value: 'something-else-value'
}];

Y la salida es algo como esto.

<select ng-model="somethingHere"  
        ng-options="option.value as option.name for option in options" 
        class="ng-pristine ng-valid">

    <option value="?" selected="selected"></option>
    <option value="0">Something Cool</option>
    <option value="1">Something Else</option>
</select>

¿Cómo es posible establecer la primera opción en los datos como el valor predeterminado para obtener un resultado como este?

<select ng-model="somethingHere" ....>
    <option value="0" selected="selected">Something Cool</option>
    <option value="1">Something Else</option>
</select>
iConnor
fuente
3
Sería bueno si hubiera una respuesta que no suponga que se está utilizando angular para construir las opciones. ¿Qué pasa si las opciones ya son parte del marcado?
pspahn
1
@pspahn: de acuerdo con docs.angularjs.org/api/ng/directive/ngOptions : solo las a **single** hard-coded <option> element ... can be nested into the <select> element.opciones no pueden formar parte del marcado.
El DIMM Reaper
1
@pspahn que no respondería al OP, pero una pregunta bastante diferente ...
Mario Trucco

Respuestas:

366

Simplemente puede usar ng-init así

<select ng-init="somethingHere = options[0]" 
        ng-model="somethingHere" 
        ng-options="option.name for option in options">
</select>
zs2020
fuente
20
Tuve un problema con este funcionamiento, fue que estaba usando 'track by', eliminarlo solucionó el problema, por si acaso eso ayuda a alguien en el
futuro
61
No hay nada malo con esta respuesta, pero ng-init falló en mi caso específico. El problema era que el valor que estaba usando todavía no estaba disponible cuando ng-init se ejecutó: obtuve el valor a través de una llamada ajax y en ese momento el ng-init ya estaba terminado. Al final utilicé un observador en ese valor y en esa función hice lo mismo que hice en ng-init. Eso funciono.
maurits
2
Yo también tuve problemas para resolver esto, el comentario de @maurits me llevó a este stackoverflow.com/questions/22348886 ¡Disfruta!
Michael
55
La documentación de Angular dice que para usar mejor el controlador $ scope para inicializar este tipo de valores docs.angularjs.org/api/ng/directive/ngInit
Fortuna
3
advertencia: el uso de ng-init para este propósito puede conducir a llamadas excesivas al método $ digest (), lo que puede hacer que la salida de su consola se vea roja y fea con mensajes como "10 $ digest () iteraciones alcanzadas. ¡Abortando!"
DMac the Destroyer
235

Si desea asegurarse de que su $scope.somethingHerevalor no se sobrescriba cuando se inicializa su vista, querrá fusionar ( somethingHere = somethingHere || options[0].value) el valor en su ng-init de la siguiente manera:

<select ng-model="somethingHere" 
        ng-init="somethingHere = somethingHere || options[0].value"
        ng-options="option.value as option.name for option in options">
</select>
Ben Lesh
fuente
22
Esta solución funcionó bien y es mejor que la respuesta seleccionada.
MJ
¿No debería el ng-init verse así ng-init = "somethingHere = somethingHere || opciones [0]" ??
infinitloop
1
¿Cómo lidiar con optionsestar vacío? Como en el caso de que los optionsdatos provengan de una fuente externa.
nulo
1
@suud solo necesitaría verificar las opciones && options.length> 0 en su ng-init. Realmente, la mayor parte de esto debe hacerse en su controlador, por lo que es comprobable.
Ben Lesh
@BenLesh Si quiero escribir algo de texto (cadena) en lugar de la primera opción. ng-init="somethingHere= somethingHere || 'Select one' " Lo intenté así. Pero no funcionó. lo que está mal en mi código
codelearner
69

Prueba esto:

HTML

<select 
    ng-model="selectedOption" 
    ng-options="option.name for option in options">
</select>

Javascript

function Ctrl($scope) {
    $scope.options = [
        {
          name: 'Something Cool',
          value: 'something-cool-value'
        }, 
        {
          name: 'Something Else',
          value: 'something-else-value'
        }
    ];

    $scope.selectedOption = $scope.options[0];
}

Plunker aquí .

Si realmente desea establecer el valor que estará vinculado al modelo, cambie el ng-optionsatributo a

ng-options="option.value as option.name for option in options"

y el Javascript para

...
$scope.selectedOption = $scope.options[0].value;

Otro Plunker aquí considerando lo anterior.

Michael Benford
fuente
2
El problema es que tendría que hacer esto para un montón de cuadros seleccionados.
iConnor
No lo entendí. ¿Qué tendrías que hacer?
Michael Benford el
Tendría que hacerlo manualmente para más de 50 cuadros seleccionados
iConnor
¿Quiere decir establecer el valor predeterminado para cada cuadro de selección? Si es así, supongo que eso no está claro en tu pregunta. De todos modos, ¿estoy en lo cierto al suponer que tendría que cargar los elementos en cada cuadro de selección? Si es así, no creo que inicializar sus valores predeterminados sea un gran problema.
Michael Benford
1
Mi problema es que el índice de la opción se devuelve desde un "envío" en el formulario. Lo que necesito es lo que está llamando a option.name, que es lo que se devolvió de un formulario simple de rieles antiguos. La casilla de verificación y los botones de opción funcionan bien, ya que utiliza ng-repeat para obtener el marcado correcto. ¿Cómo obtengo el option.name devuelto al momento de enviar el formulario?
Pferrel
40

Solo una respuesta de Srivathsa Harish Venkataramana mencionótrack by cuál es realmente una solución para esto!

Aquí hay un ejemplo junto con Plunker (enlace a continuación) de cómo usar track byen select ng-options :

<select ng-model="selectedCity"
        ng-options="city as city.name for city in cities track by city.id">
  <option value="">-- Select City --</option>
</select>

Si selectedCityse define en el alcance angular y tiene una idpropiedad con el mismo valor que cualquiera idde los cityde la citieslista, se seleccionará automáticamente en la carga.

Aquí está Plunker para esto: http://plnkr.co/edit/1EVs7R20pCffewrG0EmI?p=preview

Consulte la documentación de origen para obtener más detalles: https://code.angularjs.org/1.3.15/docs/api/ng/directive/select

mikhail-t
fuente
1
Gracias, me ayudó;)
Brahim LAMJAGUAR
1
¡Increíble! ¡Gracias!
Iurii Golskyi
33

Creo que, después de incluir 'track by', puede usarlo en ng-options para obtener lo que desea, como el siguiente

 <select ng-model="somethingHere" ng-options="option.name for option in options track by option.value" ></select>

Esta forma de hacerlo es mejor porque cuando desee reemplazar la lista de cadenas con la lista de objetos, simplemente cambiará esto a

 <select ng-model="somethingHere" ng-options="object.name for option in options track by object.id" ></select>

donde algo Aquí hay un objeto con el nombre y la identificación de las propiedades, por supuesto. Tenga en cuenta que 'as' no se usa de esta manera para expresar las opciones ng, porque solo establecerá el valor y no podrá cambiarlo cuando esté usando track by

Srivathsa Harish Venkataramana
fuente
Esto es lo que funcionó para mí. Creo que angular necesitaba algo para identificar el objeto en el modelo de mi alcance como equivalente a una elección de la lista de referencia. "track by garantor.code" hizo el truco!
markbaldy
22

El uso de respuesta aceptado ng-init, pero el documento dice que evite ng-init si es posible.

El único uso apropiado de ngInit es aliasar propiedades especiales de ngRepeat, como se ve en la demostración a continuación. Además de este caso, debe usar controladores en lugar de ngInit para inicializar valores en un ámbito.

También puede usar en ng-repeat lugar de ng-optionspara sus opciones. Con ng-repeat, puede usar ng-selectedcon ng-repeatpropiedades especiales. es decir, $ index, $ impar, $ even para que esto funcione sin ningún tipo de codificación.

$first es una de las propiedades especiales de ng-repeat.

  <select ng-model="foo">
    <option ng-selected="$first" ng-repeat="(id,value) in myOptions" value="{{id}}">
      {{value}}
    </option>
  </select>

---------------------- EDITAR ----------------
Aunque esto funciona, preferiría @ mik-t's responda cuando sepa qué valor seleccionar, https://stackoverflow.com/a/29564802/454252 , que utiliza track-byyng-options sin usar ng-initong-repeat .

Esta respuesta solo debe usarse cuando debe seleccionar el primer elemento sin saber qué valor elegir. por ejemplo, estoy usando esto para la finalización automática que requiere elegir el PRIMER elemento todo el tiempo.

allenhwkim
fuente
55
Esto funciona, pero no debe usarse, ya que ng-optionses más rápido y está más optimizado que ng-repeat.
Iso
@ No estoy en desacuerdo contigo, pero ¿tienes una fuente para esa información?
Adam Plocher
1
Justo aquí, en los documentos: docs.angularjs.org/api/ng/directive/ngOptions "más flexibilidad en cómo <select>se asigna el modelo a través de la select asparte de la expresión de comprensión", "reduce el consumo de memoria al no crear un nuevo alcance para cada instancia repetida "," mayor velocidad de renderizado al crear las opciones en documentFragmentlugar de individualmente "
Iso
16

Mi solución a esto fue usar html para codificar mi opción predeterminada. Al igual que:

En HAML:

%select{'ng-model' => 'province', 'ng-options' => "province as province for province in summary.provinces", 'chosen' => "chosen-select", 'data-placeholder' => "BC & ON"}
  %option{:value => "", :selected => "selected"}
    BC &amp; ON

En HTML:

<select ng-model="province" ng-options="province as province for province in summary.provinces" chosen="chosen-select" data-placeholder="BC & ON">
  <option value="" selected="selected">BC &amp; ON</option>
</select>

Quiero que mi opción predeterminada devuelva todos los valores de mi API, es por eso que tengo un valor en blanco. También disculpe mi haml. Sé que esto no es directamente una respuesta a la pregunta del OP, pero la gente lo encuentra en Google. Espero que esto ayude a alguien más.

Penner
fuente
1
He intentado convertir esto a html pero ha fallado en todos los convertidores en línea que he probado.
iConnor
55
¿Por qué no publicar html? Quiero decir, ¿era realmente necesario publicar el código así? No es como si el OP estuviera usando un motor de plantillas en la pregunta.
arg20
14

Use el código a continuación para completar la opción seleccionada de su modelo.

<select id="roomForListing" ng-model="selectedRoom.roomName" >

<option ng-repeat="room in roomList" title="{{room.roomName}}" ng-selected="{{room.roomName == selectedRoom.roomName}}" value="{{room.roomName}}">{{room.roomName}}</option>

</select>
Jayen Chondigara
fuente
Lekker trabajado para mí. La llamada asincrónica responsable de las opciones de enlace para mi lista de selección fue un poco más lenta que la que trajo ng-model, por lo que este enfoque me ayudó mucho. Gracias Eebbesen :-)
ajaysinghdav10d
Esto también funciona para mí. Simple y entendible.
Kent Aguilar
10

Dependiendo de cuántas opciones tenga, puede colocar sus valores en una matriz y rellenar automáticamente sus opciones de esta manera

<select ng-model="somethingHere.values" ng-options="values for values in [5,4,3,2,1]">
   <option value="">Pick a Number</option>
</select>
Alex Hawkins
fuente
10

En mi caso, tuve que insertar un valor inicial solo para indicarle al usuario que seleccione una opción, por lo tanto, me gusta el siguiente código:

<select ...
    <option value="" ng-selected="selected">Select one option</option>
</select>

Cuando probé una opción con el valor! = De una cadena vacía (nula), la opción fue sustituida por angular, pero, cuando puse una opción como esa (con valor nulo), la selección aparece con esta opción.

Perdón por mi mal inglés y espero ayudar en algo con esto.

Maciel Bombonato
fuente
8

Usar selectcon ngOptionsy establecer un valor predeterminado:

Consulte la documentación de ngOptions para obtener más ngOptionsejemplos de uso.

angular.module('defaultValueSelect', [])
 .controller('ExampleController', ['$scope', function($scope) {
   $scope.data = {
    availableOptions: [
      {id: '1', name: 'Option A'},
      {id: '2', name: 'Option B'},
      {id: '3', name: 'Option C'}
    ],
    selectedOption: {id: '2', name: 'Option B'} //This sets the default value of the select in the ui
    };
}]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<body ng-app="defaultValueSelect">
  <div ng-controller="ExampleController">
  <form name="myForm">
    <label for="mySelect">Make a choice:</label>
    <select name="mySelect" id="mySelect"
      ng-options="option.name for option in data.availableOptions track by option.id"
      ng-model="data.selectedOption"></select>
  </form>
  <hr>
  <tt>option = {{data.selectedOption}}</tt><br/>
</div>

plnkr.co

Documentación oficial sobre elSELECTelementoHTMLcon enlace de datos angular.

Enlace selecta un valor que no sea de cadena mediante ngModelanálisis / formateo:

(function(angular) {
  'use strict';
angular.module('nonStringSelect', [])
  .run(function($rootScope) {
    $rootScope.model = { id: 2 };
  })
  .directive('convertToNumber', function() {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, ngModel) {
        ngModel.$parsers.push(function(val) {
          return parseInt(val, 10);
        });
        ngModel.$formatters.push(function(val) {
          return '' + val;
        });
      }
    };
  });
})(window.angular);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.1/angular.min.js"></script>
<body ng-app="nonStringSelect">
  <select ng-model="model.id" convert-to-number>
  <option value="1">One</option>
  <option value="2">Two</option>
  <option value="3">Three</option>
</select>
{{ model }}
</body>

plnkr.co

Otro ejemplo:

angular.module('defaultValueSelect', [])
 .controller('ExampleController', ['$scope', function($scope) {
   $scope.availableOptions = [
     { name: 'Apple', value: 'apple' }, 
     { name: 'Banana', value: 'banana' }, 
     { name: 'Kiwi', value: 'kiwi' }
   ];
   $scope.data = {selectedOption : $scope.availableOptions[1].value};
}]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<body ng-app="defaultValueSelect">
  <div ng-controller="ExampleController">
  <form name="myForm">
    <select ng-model="data.selectedOption" required ng-options="option.value as option.name for option in availableOptions"></select>
  </form>  
  </div>
</body>

jsfiddle

shilovk
fuente
4

Esto funcionó para mí.

<select ng-model="somethingHere" ng-init="somethingHere='Cool'">
    <option value="Cool">Something Cool</option>
    <option value="Else">Something Else</option>
</select>
Bishan
fuente
3

En mi caso, ya que el valor predeterminado varía de un caso a otro en el formulario. Agrego un atributo personalizado en la etiqueta de selección.

 <select setSeletected="{{data.value}}">
      <option value="value1"> value1....
      <option value="value2"> value2....
       ......

en las directivas creé un script que verifica el valor y cuando angular lo llena establece la opción con ese valor a seleccionado.

 .directive('setSelected', function(){
    restrict: 'A',
    link: (scope, element, attrs){
     function setSel=(){
     //test if the value is defined if not try again if so run the command
       if (typeof attrs.setSelected=='undefined'){             
         window.setTimeout( function(){setSel()},300) 
       }else{
         element.find('[value="'+attrs.setSelected+'"]').prop('selected',true);          
       }
     }
    }

  setSel()

})

acabo de traducir esto de coffescript sobre la marcha, al menos la esencia es correcta, si no es que el agujero.

No es la forma más simple, pero hágalo cuando el valor varía

Bruno
fuente
3

En respuesta a la respuesta de Ben Lesh , debería haber esta línea

ng-init="somethingHere = somethingHere || options[0]" 

en vez de

ng-init="somethingHere = somethingHere || options[0].value" 

Es decir,

<select ng-model="somethingHere"
        ng-init="somethingHere = somethingHere || options[0]"
        ng-options="option.name for option in options track by option.value">
</select>

Li Tianjiang
fuente
3

Simplemente use ng-selected="true"lo siguiente:

<select ng-model="myModel">
        <option value="a" ng-selected="true">A</option>
        <option value="b">B</option>
</select>
Shevon Silva
fuente
2

Establecería el modelo en el controlador. Entonces, la selección tendrá ese valor por defecto. Ej: html:

<select ng-options="..." ng-model="selectedItem">

Controlador angular (usando recursos):

myResource.items(function(items){
  $scope.items=items;
  if(items.length>0){
     $scope.selectedItem= items[0];
//if you want the first. Could be from config whatever
  }
});
Jens Alenius
fuente
2

Esto funciona para mi

ng-selected="true" 
No lo sé
fuente
La mejor manera es usarlo ng-initporque está configurando un ngModel.
Juanjo Salvador
1

Si está utilizando ng-optionspara renderizar, desplegable que optiontiene el mismo valor que ng-modal está seleccionado por defecto. Considere el ejemplo:

<select ng-options="list.key as list.name for list in lists track by list.id" ng-model="selectedItem">

Entonces, la opción que tiene el mismo valor de list.keyy selectedItem, está seleccionada por defecto.

Rubi Saini
fuente
1

Necesitaba la opción predeterminada "Seleccione" para que no se pueda seleccionar. También necesitaba poder configurar condicionalmente una opción seleccionada por defecto.

Logré esto de la siguiente manera simplista: Código JS: // Voltee estos 2 para probar el valor predeterminado seleccionado o no predeterminado con el texto predeterminado "Please Select" //$scope.defaultOption = 0; $ scope.defaultOption = {clave: '3', valor: 'Opción 3'};

$scope.options = [
   { key: '1', value: 'Option 1' },
   { key: '2', value: 'Option 2' },
   { key: '3', value: 'Option 3' },
   { key: '4', value: 'Option 4' }
];

getOptions();

function getOptions(){
    if ($scope.defaultOption != 0)
    { $scope.options.selectedOption = $scope.defaultOption; }
}

HTML:

<select name="OptionSelect" id="OptionSelect" ng-model="options.selectedOption" ng-options="item.value for item in options track by item.key">
<option value="" disabled selected style="display: none;"> -- Please Select -- </option>
</select>
<h1>You selected: {{options.selectedOption.key}}</h1>         

Espero que esto ayude a alguien que tenga requisitos similares.

El "Por favor seleccione" se logró a través de la respuesta de Joffrey Outtier aquí .

Spencer Sullivan
fuente
0

Si tiene algo en lugar de solo iniciar la parte de fecha, puede usarlo ng-init()declarándolo en su controlador y usarlo en la parte superior de su HTML. Esta función funcionará como un constructor para su controlador, y puede iniciar sus variables allí.

angular.module('myApp', [])
 .controller('myController', ['$scope', ($scope) => {
   $scope.allOptions = [
     { name: 'Apple', value: 'apple' }, 
     { name: 'Banana', value: 'banana' }
   ];
   $scope.myInit = () => {
      $scope.userSelected = 'apple'
      // Other initiations can goes here..
   }
}]);


<body ng-app="myApp">
  <div ng-controller="myController" ng-init="init()">
    <select ng-model="userSelected" ng-options="option.value as option.name for option in allOptions"></select>
   </div>
</body>
ofir_aghai
fuente
0
    <!--
    Using following solution you can set initial 
default value at controller as well as after change option selected value shown as default.
    -->
    <script type="text/javascript">
      function myCtrl($scope)
        {
          //...
            $scope.myModel=Initial Default Value; //set default value as required
          //..
        }
    </script>
    <select ng-model="myModel" 
                ng-init="myModel= myModel"
                ng-options="option.value as option.name for option in options">
        </select>
Mohammad Rahman
fuente
0

intente esto en su controlador angular ...

$ somethingHere = {name: 'Something Cool'};

Puede establecer un valor, pero está utilizando un tipo complejo y el angular buscará la clave / valor para establecer en su vista.

Y, si no funciona, intente esto: ng-options = "option.value as option.name para option en options track by option.name"

Wesley Rocha
fuente
-1

Creo que la forma más fácil es

 ng-selected="$first"
Cesar Alonso
fuente
66
Esta respuesta proporciona contexto cero.
pspahn