Como defino a propriedade value nas ng-options do AngularJS?

557

Aqui está o que parece estar incomodando muitas pessoas (inclusive eu).

Ao usar a ng-optionsdiretiva no AngularJS para preencher as opções de uma <select>tag, não consigo descobrir como definir o valor de uma opção. A documentação para isso é realmente incerta - pelo menos para um simplório como eu.

Posso definir o texto para uma opção facilmente assim:

ng-options="select p.text for p in resultOptions"

Quando resultOptionsé, por exemplo:

[
    {
        "value": 1,
        "text": "1st"
    },
    {
        "value": 2,
        "text": "2nd"
    }
]

Deve ser (e provavelmente é) a coisa mais simples para definir os valores das opções, mas até agora não entendi.

Jukka Puranen
fonte
12
Tive o mesmo problema porque não achei os documentos (como mostrado abaixo) muito claros.
22912 benvds
1
O uso de "select", como é descrito na pergunta, está essencialmente errado, porque "select", neste contexto, não é uma palavra-chave, mas é um espaço reservado para uma expressão. Isso é da documentação do AngularJS: "select: O resultado dessa expressão será vinculado ao modelo do elemento pai. Se não especificado, a expressão select será padronizada para valor". Forneci mais detalhes na minha resposta abaixo.
Majix 5/05
Para mim, esta é a melhor resposta. stackoverflow.com/questions/12139152/…
Sanjay
1
Nota: Para que as opções ng funcionem, o modelo ng é obrigatório !!!!!!!!! Ref: stackoverflow.com/a/13049740/234110
Anand Rockzz

Respostas:

698

Veja ngOptions

ngOptions (opcional) - { comprehension_expression=} - em uma das seguintes formas:

Para fontes de dados da matriz : label for value in array select as label for value in array label group by group for value in array select as label group by group for value in array track by trackexpr Para fontes de dados do objeto: label for (key , value) in object select as label for (key , value) in object label group by group for (key, value) in object select as label group by group for (key, value) in object

No seu caso, deve ser

array = [{ "value": 1, "text": "1st" }, { "value": 2, "text": "2nd" }];

<select ng-options="obj.value as obj.text for obj in array"></select>

Atualizar

Com as atualizações no AngularJS, agora é possível definir o valor real para o valueatributo do selectelemento com track byexpressão.

<select ng-options="obj.text for obj in array track by obj.value">
</select>

Como se lembrar dessas coisas feias

Para todas as pessoas que estão tendo dificuldades para se lembrar desta forma de sintaxe: Concordo que essa não é a sintaxe mais fácil ou bonita. Essa sintaxe é uma espécie de versão estendida das compreensões de lista do Python e do conhecimento que me ajuda a lembrar a sintaxe com muita facilidade. É algo como isto:

Código Python:

my_list = [x**2 for x in [1, 2, 3, 4, 5]]
> [1, 4, 9, 16, 25]

# Let people to be a list of person instances
my_list2 = [person.name for person in people]
> my_list2 = ['Alice', 'Bob']

Esta é realmente a mesma sintaxe que a primeira listada acima. No entanto, <select>geralmente precisamos diferenciar entre o valor real no código e o texto mostrado (o rótulo) em um <select>elemento.

Como, precisamos person.idno código, mas não queremos mostrar idao usuário; queremos mostrar o nome dele. Da mesma forma, não estamos interessados ​​no person.namecódigo. Aí vem a aspalavra-chave para rotular as coisas. Então fica assim:

person.id as person.name for person in people

Ou, em vez de person.idprecisarmos da própria personinstância / referência. Ver abaixo:

person as person.name for person in people

Para objetos JavaScript, o mesmo método também se aplica. Lembre-se de que os itens no objeto são desconstruídos com (key, value)pares.

Umur Kontacı
fonte
33
Seu exemplo não preenche o atributo value da opção Ele define o que seria armazenado no modelo do elemento <select>. Ver diferença entre obj.Value como obj.text e obj.text
Artem Andreev
57
Estranho, mas recebo <option value = "0"> 1º </option>, <option value = "1"> 2º </option> no Chrome e no FF.
Artem Andreev
49
Não é bug, é um recurso. angularjs lida com ngOptions e ngModel internamente, dessa forma, você pode usar qualquer tipo de objeto como valor na opção, em vez de apenas cadeias. Você nunca deve tentar obter o valor da seleção ao contrário, basta usar o ngModel que você anexou para selecionar o elemento.
Umur Kontacı
4
Eu peço desculpa mas não concordo. Internamente, a diretiva select poderia facilmente usar seu próprio modelo invisível para rastrear qual opção está selecionada. Mesmo que não rastreie o valor do modelo internamente, ele pode pelo menos renderizar as opções e apenas adicionar e selecionar a opção vazia (que é o comportamento que ele faz agora se você definir o modelo para um valor que não esteja no conjunto de opções) . A única dependência para mostrar opções são as próprias opções - o princípio POLA se aplica aqui.
Ezequiel Victor
3
Por que esta resposta tem tantos votos positivos quando não fornece a resposta? A resposta de frm.adiputra está correta.
Noishe
136

Como o valor atribui seu valor:

  • Ao usar uma matriz como fonte de dados, será o índice do elemento da matriz em cada iteração;
  • Ao usar um objeto como fonte de dados, ele será o nome da propriedade em cada iteração.

Portanto, no seu caso, deve ser:

obj = { '1': '1st', '2': '2nd' };

<select ng-options="k as v for (k,v) in obj"></select>
frm.adiputra
fonte
15
+1 para explicar como Angular define o atributo de valor dos elementos de opção.
Mark Rajcok
1
Isso não define um valor. Valores padrão para números. Mas você não pode realmente especificar um "valor" .. ridículo ..
Trip
13
@ Trip, se você 'inspecionar' as opções selecionadas, verá números, mas se observar o valor limite no modelo, nesse caso, o valor será o valor 'k'. É confuso. O blesh tem um problema que mostra isso nesta resposta: stackoverflow.com/questions/13047923/… plnkr.co/edit/vJOljg?p=preview
TsenYing
4
Isso deve ser incluído no documento angular, curto e preciso. 1
devric
2
Esta é a única solução que funcionou para mim. Que dor de cabeça desagradável.
Jon
121

Eu também tive esse problema. Não consegui definir meu valor em ng-options. Todas as opções geradas foram configuradas com 0, 1, ..., n.

Para acertar, fiz algo parecido com isto nas minhas opções ng:

HTML:

<select ng-options="room.name for room in Rooms track by room.price">
    <option value="">--Rooms--</option>
</select>

Eu uso "rastrear por" para definir todos os meus valores com room.price.

(Este exemplo é péssimo: porque se houvesse mais de um preço igual, o código falharia. Portanto, certifique-se de ter valores diferentes.)

JSON:

$scope.Rooms = [
            { name: 'SALA01', price: 100 },
            { name: 'SALA02', price: 200 },
            { name: 'SALA03', price: 300 }
        ];

Aprendi no post do blog Como definir o valor inicial selecionado de um elemento de seleção usando as opções ng de Angular.JS e rastrear por .

Assista o vídeo. É uma ótima aula :)

Bruno Gomes
fonte
8
Isso funciona perfeitamente. Além disso, permite usar um elemento datalist com um <select> contido, para que o datalist possa referenciar as opções através de seu valor. Obrigado @Bruno Gomes
climboid
3
esta é a única solução que funciona para mim. obrigado.
Niner 14/05
9
Esta é a resposta mais apropriada para as ng-options com o valor da caixa de opção para corresponder ao array / objeto. Eu daria 10000 pontos para você por salvar o dia a todos se houver um sistema de troca de recompensas. Sintaxe mais bizarra da equipe angular.
Webblover
2
OBRIGADO! Isso foi tão frustrante por um longo tempo!
21413 Sean
2
Espero que os preços dos quartos nunca sejam os mesmos, porque isso acaba.
Nilskp
47

Se você deseja alterar o valor de seus optionelementos porque o formulário será enviado ao servidor, em vez de fazer isso,

<select name="text" ng-model="text" ng-options="select p.text for p in resultOptions"></select>

Você consegue fazer isso:

<select ng-model="text" ng-options="select p.text for p in resultOptions"></select>
<input type="hidden" name="text" value="{{ text }}" />

O valor esperado será enviado através do formulário com o nome correto.

neemzy
fonte
2
Eu acrescentaria que, em vez de usar <input type="hidden" name="text" value="{{ text }}" />, eu usaria ng-value. Assim: <input type="hidden" name="text" ng-value="{{ text }}" />.
Dan Atkinson
para esclarecer no meu caso, não estou enviando o formulário através do Angular usando uma postagem json - em vez disso, estou enviando o formulário normalmente usando http post, substituindo os valores que o Angular coloca na tag <options> me permite enviar o correto valor (obrigado!). Eu não precisava usar o valor ng na entrada oculta, mas precisava definir a tag de valor como as notas de postagem originais.
FireDragon
26

Para enviar um valor personalizado chamado my_heroao servidor usando um formulário normal, envie:

JSON:

"heroes": [
  {"id":"iron", "label":"Iron Man Rocks!"},
  {"id":"super", "label":"Superman Rocks!"}
]

HTML:

<select ng-model="hero" ng-options="obj.id as obj.label for obj in heroes"></select>
<input type="hidden" name="my_hero" value="{{hero}}" />

O servidor receberá um ironou supercomo o valor de my_hero.

Isso é semelhante à resposta de @neemzy , mas especificando dados separados para o valueatributo.

Philip Bulley
fonte
24

Parece ng-optionscomplicado de usar (possivelmente frustrante), mas, na realidade, temos um problema de arquitetura.

O AngularJS serve como uma estrutura MVC para um aplicativo HTML + JavaScript dinâmico. Embora seu componente (V) iew ofereça "modelagem" de HTML, seu principal objetivo é conectar as ações do usuário, através de um controlador, a alterações no modelo. Portanto, o nível apropriado de abstração, do qual trabalhar no AngularJS, é que um elemento de seleção define um valor no modelo para um valor de uma consulta .

  • Como uma fila de consulta é apresentada ao usuário é a (V) a preocupação de iew e ng-optionsfornece a forpalavra-chave para ditar o que o conteúdo do elemento de opção deve ser isto p.text for p in resultOptions .
  • Como uma linha selecionada é apresentada ao servidor é a preocupação do (M) odel. Portanto, ng-optionsfornece a aspalavra-chave para especificar qual valor é fornecido ao modelo como em k as v for (k,v) in objects.

A solução correta para esse problema é de natureza arquitetônica e envolve a refatoração do HTML para que o (M) odel execute a comunicação do servidor quando necessário (em vez de o usuário enviar um formulário).

Se uma página HTML do MVC for desnecessária engenharia excessiva para o problema em questão: use apenas a parte de geração HTML do componente iew do AngularJS (V). Nesse caso, siga o mesmo padrão usado para gerar elementos como &lt;li /&gt;'s under &lt;ul /&gt;' e coloque um ng-repeat em um elemento opcional:

<select name=“value”>
    <option ng-repeat=“value in Model.Values value=“{{value.value}}”>
        {{value.text}}
    </option>
</select>

Como kludge , sempre é possível mover o atributo name do elemento select para um elemento de entrada oculto:

<select ng-model=“selectedValue ng-options=“value.text for value in Model.Values”>
</select>
<input type=“hidden name=“value value=“{{selectedValue}}” />
Joshcodes
fonte
desempenho ruim ao usar ng-repeat em um elemento opcional, possivelmente? você deve usar as opções ng na própria seleção.
DrCord
@DrCord: O uso de ng-repeat no elemento option é oferecido como solução apenas em casos isolados (quando uma página MVC HTML adequada é desnecessária em excesso de engenharia). Talvez o eleitor não tenha preparado muito de perto. Ele será editado para chamar mais especificamente que o elemento de opção ng-repeat on não é o caso ideal.
precisa saber é o seguinte
1
Como um N00b Angular, eu teria selecionado essa solução porque, em primeira instância, parece uma sugestão justa e provavelmente funcionará. A sintaxe sugerida em outras respostas é, para dizer o mínimo, bizarra - mesmo que uma das muitas opções funcione. É uma solução legítima e se evita a otimização prematura, tudo bem. A votação para baixo é apenas o que parece.
Ian Lewis
2
É o que diz no site do AngularJS: docs.angularjs.org/api/ng/directive/select . "Note: ngOptions provides an iterator facility for the <option> element which should be used instead of ngRepeat when you want the select model to be bound to a non-string value. This is because an option element can only be bound to string values at present.". Não há menção de desempenho, apenas que ngOptions é uma alternativa ao ngRepeat.
Ian Lewis
@IanLewis, obrigado, isso faz sentido. Não fazia sentido para mim por que o ngRepeat teria menos desempenho nas opções de uma seleção não acoplada do que em uma tag <li>.
Joshcodes
20

Você consegue fazer isso:

<select ng-model="model">
    <option value="">Select</option>
    <option ng-repeat="obj in array" value="{{obj.id}}">{{obj.name}}</option>
</select>

- ATUALIZAÇÃO

Após algumas atualizações, a solução do usuário frm.adiputra é muito melhor. Código:

obj = { '1': '1st', '2': '2nd' };
<select ng-options="k as v for (k,v) in obj"></select>
Liko
fonte
8
É melhor usar ng-options dentro do elemento / diretiva select. Por exemplo, <selecione ng-model = "modelo" ng-options = "obj.id como obj.name para obj na matriz">. O que você tem funciona, mas não funciona com outras construções angulares. Por exemplo, este ng-click não funciona com o seu código: <a ng-click="model=1"> selecione 1 </a>, mas funciona se as ng-options forem usadas.
Mark Rajcok
Acabei de aparecer um bug estranho por fazer dessa maneira. Muitas pesquisas dolorosas me levaram à descoberta das opções ng, e o bug desapareceu. O modelo ng parece exigir que o atributo value das opções seja numérico e ascendente de 0. Se você alterar o valor para um índice não numérico usando as tags ng-repeat e <option>, as alterações no modelo nem sempre refletir na caixa de seleção.
Noishe
14

Hoje luto com esse problema. Eu li a documentação do AngularJS, esta e outras postagens e alguns blogs que eles levam. Todos eles me ajudaram a detalhar os detalhes, mas no final isso parece ser um tópico confuso. Principalmente por causa das muitas nuances sintáticas de ng-options.

No final, para mim, tudo se reduz a menos.

Dado um escopo configurado da seguinte maneira:

        //Data used to populate the dropdown list
        $scope.list = [
           {"FirmnessID":1,"Description":"Soft","Value":1},         
           {"FirmnessID":2,"Description":"Medium-Soft","Value":2},
           {"FirmnessID":3,"Description":"Medium","Value":3}, 
           {"FirmnessID":4,"Description":"Firm","Value":4},     
           {"FirmnessID":5,"Description":"Very Firm","Value":5}];

        //A record or row of data that is to be save to our data store.
        //FirmnessID is a foreign key to the list specified above.
        $scope.rec = {
           "id": 1,
           "FirmnessID": 2
        };

Isso é tudo o que eu precisava para obter o resultado desejado:

        <select ng-model="rec.FirmnessID"
                ng-options="g.FirmnessID as g.Description for g in list">
            <option></option>
        </select>   

Observe que eu não usei track by. O uso track bydo item selecionado sempre retornaria o objeto que correspondia ao FirmnessID, em vez do FirmnessID. Isso agora atende aos meus critérios, que é que ele retorne um valor numérico em vez do objeto, e use ng-optionspara obter a melhoria de desempenho que ele fornece, não criando um novo escopo para cada opção gerada.

Além disso, eu precisava da primeira linha em branco, então simplesmente adicionei um <option>ao <select>elemento.

Aqui está um Plunkr que mostra o meu trabalho.

Jeffrey A. Gochin
fonte
Lenda. Isso é exatamente o que eu precisava. Obrigado
Kildareflare
Ótimo, mas qual é o objetivo das chaves "Valor"? Eles não parecem ser necessários.
precisa saber é o seguinte
Não é relevante para o exemplo. Eles são simplesmente parte dos dados originais fornecidos pelo meu cliente.
Jeffrey A. Gochin 08/07/2015
11

Em vez de usar o novo recurso 'rastrear por', você pode simplesmente fazer isso com uma matriz se quiser que os valores sejam os mesmos do texto:

<select ng-options="v as v for (k,v) in Array/Obj"></select>

Observe a diferença entre a sintaxe padrão, que tornará os valores as chaves do objeto / matriz e, portanto, 0,1,2 etc. para uma matriz:

<select ng-options"k as v for (k,v) in Array/Obj"></select>

k como v se torna v como v .

Descobri isso apenas com base no senso comum, observando a sintaxe. (k, v) é a instrução real que divide a matriz / objeto em pares de valores-chave.

Na instrução 'k as v', k será o valor ev será a opção de texto exibida ao usuário. Eu acho que 'rastrear' é bagunçado e exagerado.

KthProg
fonte
Waaaaat? Funciona para matrizes em todo o lugar nas minhas páginas, estamos usando a mesma versão do AngularJS?
KthProg
11

Isso foi mais adequado para todos os cenários, de acordo comigo:

<select ng-model="mySelection.value">
   <option ng-repeat="r in myList" value="{{r.Id}}" ng-selected="mySelection.value == r.Id">{{r.Name}}
   </option>
</select>

onde você pode usar seu modelo para ligar os dados. Você obterá o valor que o objeto conterá e a seleção padrão com base no seu cenário.

azul
fonte
Adoro esta solução. Seus ajudantes angulares para esta diretiva são desnecessariamente complexos. Obrigado por ser o auto proclamado juiz de uso.
precisa
9

Foi assim que resolvi isso. Acompanhei a seleção por valor e configurei a propriedade do item selecionado para o modelo no meu código JavaScript.

Countries =
[
    {
        CountryId = 1, Code = 'USA', CountryName = 'United States of America'
    },
    {
       CountryId = 2, Code = 'CAN', CountryName = 'Canada'
    }
]
<select ng-model="vm.Enterprise.AdminCountry" ng-options="country.CountryName for country in vm.Countries track by country.CountryId">

vmé meu controlador e o país no controlador recuperado do serviço é {CountryId =1, Code = 'USA', CountryName='United States of America'}.

Quando selecionei outro país no menu suspenso de seleção e postei minha página com "Salvar", vinculei o país correto.

Archna
fonte
8

A ng-optionsdiretiva não define o atributo value nos <options>elementos para matrizes:

Usando limit.value as limit.text for limit in limitsmeios:

defina o <option>rótulo de como limit.text
salvar o limit.valuevalor nasng-model

Consulte a pergunta Estouro de pilha: ng-options do AngularJS não renderizando valores .

timestopper
fonte
5
<select ng-model="color" ng-options="(c.name+' '+c.shade) for c in colors"></select><br>
Anja Ishmukhametova
fonte
4

Você pode usar ng-options para obter a ligação de tag select para valorizar e exibir membros

Ao usar essa fonte de dados

countries : [
              {
                 "key": 1,
                 "name": "UAE"
             },
              {
                  "key": 2,
                  "name": "India"
              },
              {
                  "key": 3,
                  "name": "OMAN"
              }
         ]

você pode usar o abaixo para vincular sua tag de seleção ao valor e nome

<select name="text" ng-model="name" ng-options="c.key as c.name for c in countries"></select>

funciona muito bem

Wessam Al-Bakary
fonte
1
Aumente sua resposta somente de código com algumas explicações, a fim de evitar o equívoco de que o StackOverflow é um serviço gratuito de gravação de código.
Yunnosch
3

A resposta correta para esta pergunta foi fornecida pelo usuário frm.adiputra , pois atualmente essa parece ser a única maneira de controlar explicitamente o atributo value dos elementos da opção.

No entanto, eu só queria enfatizar que "selecionar" não é uma palavra-chave nesse contexto, mas é apenas um espaço reservado para uma expressão. Por favor, consulte a lista a seguir, para a definição da expressão "select", bem como outras expressões que podem ser usadas na diretiva ng-options.

O uso de select, conforme descrito na pergunta:

ng-options='select p.text for p  in resultOptions'

está essencialmente errado.

Com base na lista de expressões, parece que trackexpr pode ser usado para especificar o valor, quando as opções são fornecidas em uma matriz de objetos, mas foi usado apenas com o agrupamento.


Na documentação do AngularJS para ng-options:

  • array / objeto : uma expressão que é avaliada em um array / objeto para a iteração.
  • value : variável local que fará referência a cada item na matriz ou a cada valor de propriedade do objeto durante a iteração.
  • key : variável local que se referirá a um nome de propriedade no objeto durante a iteração.
  • label : O resultado dessa expressão será o rótulo do elemento. A expressão provavelmente se referirá à variável value (por exemplo, value.propertyName).
  • select : O resultado dessa expressão será vinculado ao modelo do elemento pai. Se não especificado, a expressão selecionada será padronizada como valor.
  • group : o resultado dessa expressão será usado para agrupar opções usando o elemento DOM.
  • trackexpr : usado ao trabalhar com uma matriz de objetos. O resultado dessa expressão será usado para identificar os objetos na matriz. O trackexpr provavelmente se referirá à variável value (por exemplo, value.propertyName).
Majix
fonte
3

Selecionar um item nas opções ng pode ser um pouco complicado, dependendo de como você define a fonte de dados.

Depois de lutar com eles por um tempo, acabei fazendo uma amostra com as fontes de dados mais comuns que eu uso. Você pode encontrá-lo aqui:

http://plnkr.co/edit/fGq2PM?p=preview

Agora, para fazer o ng-options funcionar, aqui estão algumas coisas a considerar:

  1. Normalmente, você obtém as opções de uma fonte e o valor selecionado de outra. Por exemplo:
    • states :: data para ng-options
    • user.state :: Opção para definir como selecionado
  2. Com base em 1, a coisa mais fácil / lógica a fazer é preencher a seleção com uma fonte e depois definir o valor selecionado através do código. Raramente seria melhor obter um conjunto de dados misto.
  3. O AngularJS permite que os controles selecionados contenham mais de key | label. Muitos exemplos online colocam objetos como 'chave' e, se você precisar de informações do objeto, defina-as dessa maneira, caso contrário, use a propriedade específica necessária como chave. (ID, CÓDIGO, etc. Como na amostra plckr)
  4. A maneira de definir o valor do controle suspenso / selecionar depende do número 3,

    • Se a chave suspensa for uma propriedade única (como em todos os exemplos no plunkr), basta configurá-la, por exemplo: $scope.dropdownmodel = $scope.user.state;
    • Se você definir o objeto como chave, precisará percorrer as opções, mesmo atribuir o objeto não definirá o item como selecionado, pois eles terão diferentes hashkeys, por exemplo:

      for (var i = 0, len = $scope.options.length; i < len; i++) {
        if ($scope.options[i].id == savedValue) { // Your own property here:
          console.log('Found target! ');
          $scope.value = $scope.options[i];
          break;
        }
      }

Você pode substituir saveValue pela mesma propriedade no outro objeto $scope.myObject.myProperty,.

Itzco
fonte
mais de um ano depois, agradeço a amostra do plunker. Muito útil.
bob.mazzo
3

Para mim, a resposta de Bruno Gomes é a melhor resposta.

Mas, na verdade, você não precisa se preocupar em definir a propriedade value das opções selecionadas. O AngularJS cuidará disso. Deixe-me explicar em detalhes.

Por favor, considere este violino

angular.module('mySettings', []).controller('appSettingsCtrl', function ($scope) {

    $scope.timeFormatTemplates = [{
        label: "Seconds",
        value: 'ss'
    }, {
        label: "Minutes",
        value: 'mm'
    }, {
        label: "Hours",
        value: 'hh'
    }];


    $scope.inactivity_settings = {
        status: false,
        inactive_time: 60 * 5 * 3, // 15 min (default value), that is, 900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.activity_settings = {
        status: false,
        active_time: 60 * 5 * 3, // 15 min (default value), that is,  900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.changedTimeFormat = function (time_format) {
        'use strict';

        console.log('time changed');
        console.log(time_format);
        var newValue = time_format.value;

        // do your update settings stuffs
    }
});

Como você pode ver na saída do violino, o que você escolher para as opções da caixa de seleção, é o seu valor personalizado, ou o valor 0, 1, 2 gerado automaticamente pelo AngularJS, não importa na saída, a menos que você esteja usando jQuery ou qualquer outro outra biblioteca para acessar o valor dessas opções da caixa de combinação e manipulá-lo de acordo.

Sanjay
fonte
3

Um ano após a pergunta, tive que encontrar uma resposta para essa pergunta, pois nenhuma delas deu a resposta real, pelo menos para mim.

Você perguntou como selecionar a opção, mas ninguém disse que essas duas coisas NÃO são iguais:

Se tivermos opções como esta:

$scope.options = [
    { label: 'one', value: 1 },
    { label: 'two', value: 2 }
  ];

E tentamos definir uma opção padrão como esta:

$scope.incorrectlySelected = { label: 'two', value: 2 };

Vai NÃO funcionar, mas se você tentar selecionar a opção como esta:

$scope.correctlySelected = $scope.options[1];

Ele vai TRABALHAR .

Embora esses dois objetos tenham as mesmas propriedades, o AngularJS os considera DIFERENTES porque o AngularJS é comparado pela referência .

Dê uma olhada no violino http://jsfiddle.net/qWzTb/ .

Aleks
fonte
3

Por favor, use trilha por propriedade que diferencia valores e rótulos na caixa de seleção.

Tente por favor

<select ng-options="obj.text for obj in array track by obj.value"></select>

que atribuirá rótulos com texto e valor com valor (da matriz)

Shashank Saxena
fonte
2

Para um objeto:

<select ng-model="mySelect" ng-options="key as value for (key, value) in object"></select>
EpokK
fonte
2

É sempre doloroso para os desenvolvedores com ng-options. Por exemplo: Obter um valor selecionado em branco / vazio na tag de seleção. Especialmente ao lidar com objetos JSON em ng-options, torna-se mais tedioso. Aqui eu fiz alguns exercícios sobre isso.

Objetivo: Iterar a matriz de objetos JSON por meio da opção ng e definir o primeiro elemento selecionado.

Dados:

someNames = [{"id":"1", "someName":"xyz"}, {"id":"2", "someName":"abc"}]

Na tag select, tive que mostrar xyz e abc, onde xyz deve ser selecionado sem muito esforço.

HTML:

<pre class="default prettyprint prettyprinted" style=""><code>
    &lt;select class="form-control" name="test" style="width:160px"    ng-options="name.someName for name in someNames" ng-model="testModel.test" ng-selected = "testModel.test = testModel.test || someNames[0]"&gt;
&lt;/select&gt;
</code></pre>

Pelo exemplo de código acima, você pode sair desse exagero.

Outra referência :

Sam Jha
fonte
2

O tutorial ANGULAR.JS: NG-SELECT E NG-OPTIONS me ajudou a resolver o problema:

<select id="countryId"
  class="form-control"
  data-ng-model="entity.countryId"
  ng-options="value.dataValue as value.dataText group by value.group for value in countries"></select>
Ricardo Huertas
fonte
Obrigado pelo link.
PHPst 01/02
1
<select ng-model="output">
   <option ng-repeat="(key,val) in dictionary" value="{{key}}">{{val}}</option>
</select>
ethanneff
fonte
1
ngOptions fornece alguns benefícios como a redução de memória e aumentar a velocidade, não criando um novo escopo para cada instância repetido, consulte: docs.angularjs.org/api/ng/directive/ngOptions
mggSoft
1

Execute o trecho de código e veja as variações. Aqui está uma nota para uma compreensão rápida

  1. Exemplo 1 (seleção de objeto): - ng-option="os.name for os in osList track by os.id". Aqui track by os.idé importante e deve estar lá e os.id as não deve ter antes os.name.

    • A ng-model="my_os"deve definir a um objeto com a chave como id como my_os={id: 2}.
  2. Exemplo 2 (seleção de valor): - ng-option="os.id as os.name for os in osList". Aqui track by os.id NÃO deve estar lá e os.id as deve estar lá antes os.name.

    • O ng-model="my_os"deve ser definido como um valor comomy_os= 2

O trecho de código de restante explicará.

Premchandra Singh
fonte
0

Como muitos disseram antes, se eu tiver dados, algo como isto:

countries : [
              {
                 "key": 1,
                 "name": "UAE"
             },
              {
                  "key": 2,
                  "name": "India"
              },
              {
                  "key": 3,
                  "name": "OMAN"
              }
         ]

Eu usaria como:

<select
    ng-model="selectedCountry"
    ng-options="obj.name for obj  in countries">
</select>

No seu Controller, você precisa definir um valor inicial para se livrar do primeiro item vazio:

 $scope.selectedCountry = $scope.countries[0];

 // You need to watch changes to get selected value
 $scope.$watchCollection(function() {
   return $scope.selectedCountry
 }, function(newVal, oldVal) {
     if (newVal === oldVal) {
       console.log("nothing has changed " + $scope.selectedCountry)
     } 
     else {
       console.log('new value ' + $scope.selectedCountry)
     }
 }, true)
Anjum ....
fonte
0

Aqui está como eu resolvo esse problema em um aplicativo herdado:

Em HTML:

ng-options="kitType.name for kitType in vm.kitTypes track by kitType.id" ng-model="vm.itemTypeId"

Em JavaScript:

vm.kitTypes = [
    {"id": "1", "name": "Virtual"},
    {"id": "2", "name": "Physical"},
    {"id": "3", "name": "Hybrid"}
];

...

vm.itemTypeId = vm.kitTypes.filter(function(value, index, array){
    return value.id === (vm.itemTypeId || 1);
})[0];

Meu HTML exibe o valor da opção corretamente.

techguy2000
fonte
0

Diretiva ngOptions:

$scope.items = [{name: 'a', age: 20},{ name: 'b', age: 30},{ name: 'c', age: 40}];
  • Case-1) rótulo para valor na matriz:

    <div>
        <p>selected item is : {{selectedItem}}</p>
        <p> age of selected item is : {{selectedItem.age}} </p>
        <select ng-model="selectedItem" ng-options="item.name for item in items">
        </select>
    </div>

Explicação da saída (suponha o 1º item selecionado):

selectedItem = {name: 'a', age: 20} // [por padrão, o item selecionado é igual ao item de valor ]

selectedItem.age = 20

  • Caso-2) selecione como rótulo para o valor na matriz:

    <div>
        <p>selected item is : {{selectedItem}}</p>
        <select ng-model="selectedItem" ng-options="item.age as item.name for item in items">
        </select>
    </div>

Explicação de saída (suponha o 1º item selecionado): selectedItem = 20 // [selecionar parte é item.age ]

Masud Shrabon
fonte