Por que o AngularJS inclui uma opção vazia em select?

Eu tenho trabalhado com o AngularJS nas últimas semanas, e o que realmente me incomoda é que mesmo depois de tentar todas as permutações ou a configuração definida na especificação em http://docs.angularjs.org/api/ng .directive: select , eu ainda recebo uma opção vazia como o primeiro filho do elemento select.

Aqui está o Jade:

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

Aqui o controlador:

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

Finalmente, aqui está o HTML que é gerado:

   Feature Bug Enhancement  

O que eu preciso fazer para me livrar disso?

PS: As coisas funcionam sem isso também, mas parece estranho se você usar select2 sem seleção múltipla.

A option vazia é gerada quando um valor referenciado por ng-model não existe em um conjunto de opções passadas para ng-options . Isso acontece para evitar a seleção acidental do modelo: o AngularJS pode ver que o modelo inicial é indefinido ou não no conjunto de opções e não quer decidir o valor do modelo sozinho.

Se você quiser se livrar da opção vazia, basta selecionar um valor inicial no seu controlador, algo como:

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

Aqui está o jsFiddle: http://jsfiddle.net/MTfRD/3/

Em suma: a opção vazia significa que nenhum modelo válido é selecionado (por válido quero dizer: do conjunto de opções). Você precisa selecionar um valor de modelo válido para se livrar dessa opção vazia.

Se você quer um valor inicial, veja a resposta do @pkozlowski.opensource, que também pode ser implementada na view (ao invés de no controller) usando o ng-init:

  

Se você não quiser um valor inicial, “um único elemento codificado, com o valor definido para uma string vazia, pode ser nested no elemento. Esse elemento representará, então, null ou a opção” not selected “”:

  

Angular <1,4

Para qualquer um lá fora que trate “null” como valor válido para uma das opções (então imagine que “null” é um valor de um dos itens em typeOptions no exemplo abaixo), eu achei a maneira mais simples de ter certeza de que adicionou automaticamente A opção está oculta é usar ng-if.

  

Por que ng-se e não ng-hide? Como você deseja que os seletores de css que segmentam a primeira opção acima, selecione a opção “real”, não a que está oculta. Ele é útil quando você está usando o transferidor para testes e2e e (por qualquer motivo) você usa by.css () para direcionar as opções de seleção.

Angular> = 1,4

Devido à refatoração das diretivas select e options, usar ng-if não é mais uma opção viável, então você precisa ativar ng-show="false" para fazer com que funcione novamente.

Talvez seja útil para alguém:

Se você quiser usar opções simples em vez de opções ng, você pode fazer como abaixo:

  

Defina o modelo inline. Use ng-init para se livrar da opção vazia

Entre as multidões de respostas aqui, imaginei que repostaria a solução que funcionava para mim e atenderia a todas as condições a seguir:

  • forneceu um espaço reservado / prompt quando o modelo ng é falsamente (por exemplo, ” –select region– ” w. value="" )
  • Quando o valor do ng-model for false e o usuário abrir a lista suspensa options, o placeholder é selecionado (outras soluções mencionadas aqui tornam a primeira opção selecionada selecionada, o que pode ser enganoso)
  • permitir que o usuário desmarque um valor válido, selecionando essencialmente o valor falsy / default novamente

insira a descrição da imagem aqui

código

  

src

q original e um – https://stackoverflow.com/a/32880941/1121919

Algo semelhante estava acontecendo comigo também e foi causado por um upgrade para 1.5 angular. ng-init parece estar sendo analisado para digitar em versões mais recentes do Angular. No Angular antigo ng-init="myModelName=600" seria ng-init="myModelName=600" para uma opção com valor “600” ie mas no Angular 1.5 ele não encontrará isto como parece espere encontrar uma opção com valor 600, ou seja, . Angular então inseriria um primeiro item random:

  

Angular <1.2.x

  

Angular> 1,2

  

Uma solução rápida:

 select option:empty { display:none } 

Espero que ajude alguém. Idealmente, a resposta selecionada deve ser a abordagem, mas se no caso isso não for possível, deve funcionar como um patch.

Sim ng-model irá criar um valor de opção vazio, quando ng-model property undefined. Podemos evitar isso, se atribuirmos um object ao modelo ng

Exemplo

codificação angular

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

Nota importante:

Atribuir object de array como $ scope.collections [0] ou $ scope.collections [1] para ng-model, não use propriedades de objects. se você estiver recebendo o valor da opção select do servidor, usando a function call back, atribua o object ao ng-model

NOTA do documento angular

Nota: ngModel compara por referência, não por valor. Isso é importante quando se liga a uma matriz de objects. veja um exemplo http://jsfiddle.net/qWzTb/

Eu tentei muitas vezes, finalmente eu encontrei.

Embora as respostas de @ pkozlowski.opensource e @ Mark estejam corretas, eu gostaria de compartilhar minha versão ligeiramente modificada, onde eu sempre seleciono o primeiro item da lista, independentemente do seu valor:

  

Eu enfrentei o mesmo problema. Se você está postando um formulário angular com um post normal, então você enfrentará esse problema, pois o ângulo não permite que você defina valores para as opções do modo que você usou. Se você obtiver o valor de “form.type”, encontrará o valor correto. Você tem que postar o object angular sem a postagem do formulário.

Ok, na verdade a resposta é bem simples: quando há uma opção não reconhecida pelo Angular, ela inclui uma opção sem graça. O que você está fazendo de errado é, quando você usa ng-options, ele lê um object, digamos [{ id: 10, name: test }, { id: 11, name: test2 }] right?

Isto é o valor do seu modelo para ser avaliado como igual, digamos que você deseja que o valor selecionado seja 10, você precisa definir seu modelo para um valor como { id: 10, name: test } para selecionar 10, portanto ele será NÃO crie esse lixo.

Espero que ajude todo mundo a entender, eu tive um tempo difícil tentando 🙂

Estou usando o Angular 1.4x e encontrei este exemplo, então usei o ng-init para definir o valor inicial no select:

  

Uma solução simples é definir uma opção com um valor em branco "" Descobri que isso elimina a opção extra indefinida.

Isso funcionou para mim

  

Isso funciona perfeitamente bem

  

o modo como funciona é que isso dá a primeira opção a ser exibida antes de selecionar algo e o display:none remove-o da lista suspensa, então se você quiser, pode fazer

  

e isso lhe dará o select and option antes de selecionar, mas uma vez selecionado, ele desaparecerá e não será exibido na lista suspensa.

Tente este no seu controlador, na mesma ordem:

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

Aqui está a correção:

para um exemplo de dados como:

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

A opção de seleção deve ser assim:

  

Sendo o ponto quando escrevemos value.listCount como value.listName , ele preenche automaticamente o texto em value.listName mas o valor da opção selecionada é value.listCount embora os valores mostrados como normal sejam de 0,1,2 .. e assim por diante. !!!

No meu caso, o financeRef.financeLimit está realmente pegando o value.listCount e eu posso fazer minha manipulação no controlador dinamicamente.

Eu gostaria de acrescentar que, se o valor inicial vem de uma binding de algum elemento pai ou componente 1.5, certifique-se de que o tipo apropriado é passado. Se estiver usando @ na binding, a variável passada será string e se as opções forem, por exemplo. inteiros, em seguida, a opção vazia será exibida.

Analise adequadamente o valor no init ou vincule com < e não @ (menos recomendado para desempenho, a menos que seja necessário).

Solução simples

  

Uma solução de moagem com jQuery quando você não tem o controle das opções

html:

  

js:

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

Se você usar o ng-init seu modelo para resolver este problema:

  

Eu tive o mesmo problema, eu (removido “ng-modelo”) mudou isso:

  

para isso:

  

agora está funcionando, mas no meu caso foi causa ive deletei esse escopo do ng.controller, verifique se vc não fez o mesmo.

Oi eu tive algumas referências móveis jQuery e eu as removi. Com o jQuery mobile, qualquer uma das correções acima não funcionou para mim. (É ótimo se alguém puder explicar o conflito entre o jQuery Mobile e o Angular JS)

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

A única coisa que funcionou para mim é usar o track by em ng-options , assim:

   

Esta solução funciona para mim: