Angular adiciona opções estranhas ao elemento de seleção ao definir o valor do modelo

Eu tenho um elemento select definido como tal:

 Select Country {{country.name}}  

Tudo funciona bem quando não estou definindo nenhum tipo de valor na diretiva que contém esse elemento select. Mas quando eu faço algo como newAddressForm.country_id = 98 , em vez de selecionar a opção com o valor 98, o Angular injeta um novo no topo do elemento select, da seguinte forma:

  

O que da? Que tipo de formato é isso e por que isso acontece? Note que se eu fizer um console.log(newAddressForm.country_id) na diretiva, recebo um "98" normal, é apenas estranho no HTML gerado.

Editar: atualização da situação. Comutado para usar ng-select , mas o problema persiste.

O elemento estranho não aparece mais, MAS, agora há outro elemento no topo, um que tem apenas um ponto de interrogação ? como o valor e nenhum label.

Isso é, pelo que eu percebi, a opção "none selected" do Angular. Eu ainda não entendi porque não seleciono a opção que eu digo para selecionar, no entanto.

Fazendo newAddressForm.country_id = 98 ainda não dá resultados. Por que é que?

Angular não define o valor de um elemento select para os valores reais de sua matriz e faz algumas coisas internas para gerenciar a vinculação de escopo. Veja o primeiro comentário de Mark Rajcok neste link:

https://docs.angularjs.org/api/ng/directive/select#overview

Quando o usuário seleciona uma das opções, Angular usa o índice (ou chave) para procurar o valor na matriz (ou object) – o valor pesquisado é o que o modelo está definido como. (Então, o modelo não está definido para o valor que você vê no HTML! Isso causa muita confusão.)

Eu não estou totalmente certo de que usar uma ng-repeat é a melhor opção.

Usando a seguinte syntax com ng-options resolvi este problema para mim:

  

Se seus valores forem inteiros, você deve usar “” mesmo que não sejam strings, esse simples motivo é exatamente o motivo pelo qual você está obtendo uma opção com um ponto de interrogação como um valor.

Você não deveria estar usando isso:

 { value: 0, name: "Pendiente" }, { value: 1, name: "Em andamento" }, { value: 2, name: "Erro" }, { value: 3, name: "Enviar email" }, { value: 4, name: "Enviado" } 

Este é o caminho certo:

 { value: "0", name: "Pendiente" }, { value: "1", name: "Em andamento" }, { value: "2", name: "Erro" }, { value: "3", name: "Enviar email" }, { value: "4", name: "Enviado" } 

Se você tem pelo menos um registro que não está usando “” você estará recebendo isto? valor da opção.

Eu estava me deparando com o mesmo problema no início da noite, onde vi uma opção de seleção aparecer como a primeira da minha lista, embora eu não a tenha criado explicitamente. Eu estava preenchendo uma lista de opções de seleção no meu controlador e usando a mesma syntax ng-options mencionada acima por jessedvrs (exceto que eu também estava inserindo a opção padrão “selecionar uma opção” no controlador em vez de marcá-lo no HTML como ele estava).

Por algum motivo, a lista de seleção sempre mostraria uma opção adicional no índice zero com um valor “?”, Mas quando eu mudei como preenchi minha opção padrão no controlador, esse problema desapareceu. Eu estava preenchendo as opções de seleção fazendo uma chamada de API, preenchendo-as dentro de uma promise. Eu cometi o erro de também preencher minha opção padrão “selecionar uma opção” como a primeira coisa que fiz nessa promise, mas quando eu fiz isso fora da promise (antes de fazer a chamada da API), as opções de seleção preenchiam o caminho Eu diminuí-los para.

Eu acho que a opção jessedvrs é uma solução para o problema (definindo a opção padrão na marcação HTML), mas se você preferir preencher suas opções em javascript, sugiro ainda definir a opção padrão antes de fazer chamadas para uma API ou processos que ainda podem estar em execução enquanto o HTML está sendo renderizado.

Quando você atribui um valor a algum elemento select, o AngularJS procura o valor fornecido no atributo value das tags de opção nesse elemento select. Mas o problema é que o AngularJS faz uma comparação baseada em tipos . Portanto, se os valores nas tags de opção forem strings (o que geralmente é o caso) e a variável que você associa usando ng-model for um número, o AngularJS não conseguirá encontrar o elemento de opção correspondente e, portanto, criará seu próprio elemento –

  

A solução é, enquanto se liga, converte-a para o tipo apropriado.

Neste caso, a solução seria ligar um Integer

  

Se os valores forem definidos como Strings, o truque seria usar

  

Ao enviar dados sobre a variável de escopo, podemos usar o código a seguir

 $scope.enquiryLocationRow.push({'location': EnqLocation.location, 'state_id': Number(EnqLocation.state_id), 'country_id': Number(EnqLocation.country_id)}); 

resolveu meu problema