Como ter uma opção padrão na caixa de seleção Angular.js

311

Pesquisei no Google e não consigo encontrar nada sobre isso.

Eu tenho esse código.

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

Com alguns dados como este

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

E a saída é algo como isto.

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

Como é possível definir a primeira opção nos dados como o valor padrão, para que você obtenha um resultado como este.

<select ng-model="somethingHere" ....>
    <option value="0" selected="selected">Something Cool</option>
    <option value="1">Something Else</option>
</select>
iConnor
fonte
3
Seria bom se houvesse uma resposta que não assumisse que o angular estava sendo usado para criar as opções. E se as opções já fizerem parte da marcação?
Psp2
1
@pspahn - de acordo com docs.angularjs.org/api/ng/directive/ngOptions : only a **single** hard-coded <option> element ... can be nested into the <select> element.As opções ainda não podiam fazer parte da marcação.
O DIMM Reaper
1
@pspahn que não responderia o OP, mas uma questão muito diferente ...
Mario Trucco

Respostas:

366

Você pode simplesmente usar o ng-init assim

<select ng-init="somethingHere = options[0]" 
        ng-model="somethingHere" 
        ng-options="option.name for option in options">
</select>
zs2020
fonte
20
Eu tive um problema com este trabalho, foi que eu estava usando 'track por', removê-lo corrigido o problema, apenas no caso que ajuda a alguém para baixo da linha: D
DrCord
61
Nada de errado com esta resposta, mas o ng-init falhou para mim no meu caso específico. O problema era que o valor que eu estava usando ainda não estava disponível no momento em que o ng-init foi executado: obtive o valor por meio de uma chamada ajax e naquele momento o ng-init já estava concluído. No final, usei um observador nesse valor e nessa função fiz o mesmo que no ng-init. Isso funcionou.
maurits 5/09/14
2
Eu também tive problemas para resolver isso, o comentário @maurits me levou a este stackoverflow.com/questions/22348886 Aproveite!
Michael
5
A documentação do Angular diz para usar melhor o escopo $ do controlador para inicializar esse tipo de valor docs.angularjs.org/api/ng/directive/ngInit
Fortuna
3
aviso: o uso de ng-init para esse fim pode levar a chamadas excessivas para o método $ digest (), o que pode fazer com que a saída do console fique toda vermelha e feia com mensagens como "10 $ digest () iterações atingidas. Interrompendo!"
precisa saber é o seguinte
235

Se você quiser garantir que seu $scope.somethingHerevalor não seja sobrescrito quando a sua exibição for inicializada, convém coalescer ( somethingHere = somethingHere || options[0].value) o valor no ng-init da seguinte maneira:

<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
fonte
22
Esta solução funcionou bem e é melhor que a resposta selecionada.
MJ
o ng-init não deve se parecer com isso ng-init = "somethingHere = somethingHere || opções [0]" ??
infinitloop
1
Como lidar com optionsestar vazio? Como no caso de optionsdados serem provenientes de fonte externa.
null
1
@suud, você só precisa verificar as opções && options.length> 0 no seu ng-init. Realmente, a maior parte disso deve ser feita no seu controlador, por isso é testável.
Ben Lesh 5/05
@ BenLesh Se eu quiser escrever algum texto (string) em vez da primeira opção. ng-init="somethingHere= somethingHere || 'Select one' " Eu tentei assim. mas não funcionou. o que está errado no meu código
codelearner
69

Tente o seguinte:

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

Se você realmente deseja definir o valor que será vinculado ao modelo, altere o ng-optionsatributo para

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

e o Javascript para

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

Outro Plunker aqui considerando o exposto acima.

Michael Benford
fonte
2
O problema é que eu precisaria fazer isso para várias caixas de seleção.
IConnor
Não entendi. O que você teria que fazer?
Michael Benford 12/08
Eu teria que fazê-lo manualmente para talvez 50 + caixas de seleção
iConnor
Você quer dizer definir o valor padrão para cada caixa de seleção? Nesse caso, acho que isso não está claro na sua pergunta. Enfim, tenho razão em supor que você precisaria carregar os itens em todas as caixas de seleção? Nesse caso, não acho que inicializar seus valores padrão seja um grande problema.
Michael Benford 12/08
1
Meu problema é que o índice da opção é retornado de um "envio" no formulário. O que eu preciso é o que você está chamando option.name, que é o que foi retornado de um formulário simples e antigo de trilhos. A caixa de seleção e os botões de opção funcionam bem desde que você usa ng-repeat para obter a marcação correta. Como obtenho o option.name retornado no momento do envio do formulário?
Pferrel
40

Apenas uma resposta de Srivathsa Harish Venkataramana mencionou track byque é realmente uma solução para isso!

Aqui está um exemplo junto com o Plunker (link abaixo) de como usar track byno 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>

Se selectedCityfor definido no escopo angular e tiver idpropriedade com o mesmo valor que qualquer idoutro cityna citieslista, será selecionado automaticamente no carregamento.

Aqui está Plunker para isso: http://plnkr.co/edit/1EVs7R20pCffewrG0EmI?p=preview

Consulte a documentação de origem para obter mais detalhes: https://code.angularjs.org/1.3.15/docs/api/ng/directive/select

mikhail-t
fonte
1
Graças ajudou-me;)
Brahim LAMJAGUAR
1
Impressionante! Obrigado!
Iurii Golskyi
33

Acho que, após a inclusão de 'rastrear por', você pode usá-lo em ng-options para obter o que deseja, como o seguinte

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

Essa maneira de fazê-lo é melhor porque quando você deseja substituir a lista de cadeias de caracteres por lista de objetos, altere isso para

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

where somethingHere é um objeto com o nome e o ID das propriedades, é claro. Observe que 'as' não é usado dessa maneira para expressar as opções ng, porque ele definirá apenas o valor e você não poderá alterá-lo quando estiver usando track by

Srivathsa Harish Venkataramana
fonte
Isto é o que funcionou para mim. Eu acho que angular precisava de algo para identificar o objeto no modelo do meu escopo como equivalente a uma escolha na lista de referências. "track by guarantor.code" fez o truque!
markbaldy
22

A resposta aceita é usar ng-init, mas o documento diz para evitar ng-init, se possível.

O único uso apropriado de ngInit é o alias de propriedades especiais do ngRepeat, como visto na demonstração abaixo. Além deste caso, você deve usar controladores em vez de ngInit para inicializar valores em um escopo.

Você também pode usar em ng-repeat vez de ng-optionspara suas opções. Com ng-repeat, você pode usar ng-selectedcom ng-repeatpropriedades especiais. ou seja, $ index, $ odd, $ even para fazer isso funcionar sem nenhuma codificação.

$first é uma das propriedades especiais ng-repeat.

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

---------------------- EDIT ----------------
Embora isso funcione, eu preferiria @ mik-t's responda quando souber qual valor selecionar, https://stackoverflow.com/a/29564802/454252 , que usa track-bye ng-optionssem usar ng-initou ng-repeat.

Essa resposta deve ser usada apenas quando você deve selecionar o primeiro item sem saber qual valor escolher. por exemplo, estou usando isso para preenchimento automático, o que exige a escolha do PRIMEIRO item o tempo todo.

allenhwkim
fonte
5
Isso funciona, mas não deve ser usado, pois ng-optionsé mais rápido e otimizado do que ng-repeat.
Iso
@Não discordo de você, mas você tem uma fonte para essa informação?
Adam Plocher
1
Bem aqui, nos documentos: docs.angularjs.org/api/ng/directive/ngOptions “mais flexibilidade na forma como o <select>modelo do é atribuído através da select asparte da expressão de compreensão”, “reduz o consumo de memória ao não criar um novo escopo para cada instância repetido”,‘aumentou tornar velocidade, criando as opções de uma documentFragmentvez de individualmente’
Iso
16

Minha solução para isso foi usar html para codificar minha opção padrão. Igual a:

No 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

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

Quero que minha opção padrão retorne todos os valores da minha API, é por isso que tenho um valor em branco. Também desculpe meu haml. Sei que isso não é diretamente uma resposta à pergunta do OP, mas as pessoas encontram isso no Google. Espero que isso ajude outra pessoa.

penner
fonte
1
Eu tentei converter isso em html, mas ele falhou em todos os conversores online que eu tentei.
IConnor
5
Por que não postar html? Quero dizer, postar o código assim realmente necessário? Não é como se o OP estivesse usando um mecanismo de modelo na pergunta.
arg20
14

Use o código abaixo para preencher a opção selecionada do seu 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
fonte
Lekker trabalhado para mim. A chamada assíncrona responsável pelas opções de ligação para minha lista de seleção foi um pouco mais lenta que a que trouxe o modelo ng, portanto, essa abordagem me ajudou muito. Obrigado Eebbesen :-)
ajaysinghdav10d
Isso funciona para mim também. Simples e compreensível.
Kent Aguilar
10

Dependendo de quantas opções você tem, você pode colocar seus valores em uma matriz e preencher automaticamente suas opções como esta

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

No meu caso, eu precisava inserir um valor inicial apenas para informar ao usuário para selecionar uma opção; portanto, gosto do código abaixo:

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

Quando tentei uma opção com o valor! = De uma sequência vazia (nula), a opção foi substituída por angular, mas, ao colocar uma opção como essa (com valor nulo), o select aparece com essa opção.

Desculpe pelo meu inglês ruim e espero ajudar em algo com isso.

Maciel Bombonato
fonte
8

Usando selectcom ngOptionse definindo um valor padrão:

Veja a documentação do ngOptions para mais ngOptionsexemplos 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

Documentação oficial sobre oSELECTelementoHTMLcom ligação de dados angular.

Vinculação selecta um valor não-string via ngModelanálise / formatação:

(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

Outro exemplo:

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

Isso funcionou para mim.

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

No meu caso, já que o padrão varia de caso para caso no formulário. Eu adiciono um atributo personalizado na tag select.

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

nas diretivas, criei um script que verifica o valor e, quando preenchido pelo angular, define a opção com esse valor para selecionado.

 .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()

})

acabei de traduzir isso de coffescript on the fly pelo menos o jist está correto, se não o buraco.

Não é a maneira mais simples, mas faça-o quando o valor variar

Bruno
fonte
3

Em resposta à resposta de Ben Lesh , deve haver esta linha

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

ao invés de

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

Isso é,

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

Basta usar ng-selected="true"o seguinte:

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

Eu definiria o modelo no controlador. Em seguida, a seleção assumirá o valor padrão. Por exemplo: html:

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

Controlador angular (usando recurso):

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

Isso funciona para mim

ng-selected="true" 
Eu não sei
fonte
A melhor maneira é usar ng-initporque você está configurando um ngModel.
Juanjo Salvador 26/10
1

Se você estiver usando ng-optionspara renderizar, o menu suspenso optioncom o mesmo valor de ng-modal é o padrão selecionado. Considere o exemplo:

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

Portanto, a opção com o mesmo valor de list.keye selectedItem, é o padrão selecionado.

Rubi saini
fonte
1

Eu precisava que o padrão "Por favor, selecione" não fosse selecionável. Eu também precisava ser capaz de definir condicionalmente uma opção selecionada padrão.

Consegui isso da seguinte maneira simplista: Código JS: // Vire esses 2 para testar o padrão selecionado ou nenhum padrão com o texto “Por favor, selecione” //$scope.defaultOption = 0; $ scope.defaultOption = {chave: '3', valor: 'Opção 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 isso ajude alguém que tenha requisitos semelhantes.

O "Please Select" foi realizado através da resposta de Joffrey Outtier aqui .

Spencer Sullivan
fonte
0

Se você tem alguma coisa em vez de apenas iniciar a parte da data, pode usar ng-init() la declarando-a no seu controlador e na parte superior do seu HTML. Esta função funcionará como um construtor para o seu controlador e você poderá iniciar suas variáveis ​​lá.

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

tente isso no seu controlador angular ...

$ somethingHere = {name: 'Algo legal'};

Você pode definir um valor, mas está usando um tipo complexo e o angular procurará a chave / valor para definir em sua exibição.

E, se não funcionar, tente o seguinte: ng-options = "option.value as option.name para a opção nas opções track by option.name"

Wesley Rocha
fonte
-1

Eu acho que a maneira mais fácil é

 ng-selected="$first"
Cesar Alonso
fonte
6
Esta resposta fornece zero contexto.
Psp2