Trabalhando com select usando as opções ng do AngularJS

Eu li sobre isso em outros posts, mas não consegui descobrir.

Eu tenho uma matriz

$scope.items = [ {ID: '000001', Title: 'Chicago'}, {ID: '000002', Title: 'New York'}, {ID: '000003', Title: 'Washington'}, ]; 

Eu quero renderizá-lo como:

  Chicago New York Washington  

E também quero selecionar a opção com ID = 000002.

Eu li selecionar e tentei, mas não consigo descobrir.

Uma coisa a notar é que o ngModel é necessário para que ngOptions funcionem … note o ng-model="blah" que está dizendo “set $ scope.blah para o valor selecionado”.

Tente isto:

  

Aqui está mais da documentação do AngularJS (se você ainda não viu):

para fonts de dados de matriz:

  • rotular para valor na matriz
  • selecione como label para valor na matriz
  • label grupo por grupo para valor na matriz = selecione como label grupo por grupo para valor na matriz

para fonts de dados de objects:

  • label for (key, value) no object
  • selecione como label para (chave, valor) no object
  • label group by group para (chave, valor) no object
  • selecione como grupo de label por grupo para (chave, valor) no object

Para alguns esclarecimentos sobre valores de tag de opção no AngularJS:

Quando você usa ng-options , os valores das tags de opções escritas por ng-options serão sempre o índice do item da matriz ao qual a tag da opção está relacionada . Isso ocorre porque o AngularJS na verdade permite que você selecione objects inteiros com controles de seleção, e não apenas tipos primitivos. Por exemplo:

 app.controller('MainCtrl', function($scope) { $scope.items = [ { id: 1, name: 'foo' }, { id: 2, name: 'bar' }, { id: 3, name: 'blah' } ]; }); 
 
{{selectedItem | json}}

Os $scope.selectedItem acima permitirão que você selecione um object inteiro em $scope.selectedItem diretamente. O ponto é que, com o AngularJS, você não precisa se preocupar com o que está na sua tag de opção. Deixe o AngularJS lidar com isso; você deve se preocupar apenas com o que está em seu modelo em seu escopo.

Aqui está um plunker demonstrando o comportamento acima e mostrando o HTML escrito


Lidando com a opção padrão:

Há algumas coisas que não mencionei acima relacionadas à opção padrão.

Selecionando a primeira opção e removendo a opção vazia:

Você pode fazer isso adicionando um ng-init simples que define o modelo (de ng-model ) para o primeiro elemento nos itens que você está repetindo em ng-options :

  

Nota: Isso pode ficar um pouco louco se foo for inicializado corretamente para algo “falso”. Nesse caso, você vai querer lidar com a boot do foo no seu controlador, provavelmente.

Personalizando a opção padrão:

Isto é um pouco diferente; aqui, tudo o que você precisa fazer é adicionar uma tag de opção como filha do seu select, com um atributo value vazio, depois personalizar seu texto interno:

  

Nota: Neste caso, a opção “vazio” permanecerá lá mesmo depois de selecionar uma opção diferente. Este não é o caso para o comportamento padrão de seleções sob o AngularJS.

Uma opção padrão personalizada que é ocultada após a seleção:

Se você quiser que sua opção padrão personalizada desapareça depois de selecionar um valor, poderá adicionar um atributo ng-hide à sua opção padrão:

  

Estou aprendendo AngularJS e também estava lutando com a seleção. Eu sei que esta pergunta já foi respondida, mas eu queria compartilhar mais algum código, no entanto.

No meu teste eu tenho duas checkboxs de listview: marcas de carros e modelos de carros. A lista de modelos está desativada até que alguma marca seja selecionada. Se a seleção em make listbox for redefinida posteriormente (definida como ‘Select Make’), a checkbox de listview de modelos será desativada novamente E a seleção também será redefinida (para ‘Select Model’). As marcas são recuperadas como um recurso, enquanto os modelos são apenas codificados.

Faz o JSON:

 [ {"code": "0", "name": "Select Make"}, {"code": "1", "name": "Acura"}, {"code": "2", "name": "Audi"} ] 

services.js:

 angular.module('makeServices', ['ngResource']). factory('Make', function($resource){ return $resource('makes.json', {}, { query: {method:'GET', isArray:true} }); }); 

Arquivo HTML:

 
Make
Model

controllers.js:

 function MakeModelCtrl($scope) { $scope.makeNotSelected = true; $scope.make = {selected: "0"}; $scope.makes = Make.query({}, function (makes) { $scope.make = {selected: makes[0].code}; }); $scope.makeChanged = function(selectedMakeCode) { $scope.makeNotSelected = !selectedMakeCode; if ($scope.makeNotSelected) { $scope.model = {selected: "0"}; } }; $scope.models = [ {code:"0", name:"Select Model"}, {code:"1", name:"Model1"}, {code:"2", name:"Model2"} ]; $scope.model = {selected: "0"}; } 

Por alguma razão, o AngularJS me deixa confuso. Sua documentação é bastante horrível sobre isso. Mais bons exemplos de variações seriam bem-vindos.

De qualquer forma, tenho uma ligeira variação na resposta de Ben Lesh.

Minha coleção de dados é assim:

 items = [ { key:"AD",value:"Andorra" } , { key:"AI",value:"Anguilla" } , { key:"AO",value:"Angola" } ...etc.. ] 

Agora

  

ainda resultou no valor das opções para ser o índice (0, 1, 2, etc.).

Adicionando Track Fixou para mim:

  

Eu acho que acontece com mais freqüência que você quer adicionar uma matriz de objects em uma lista de seleção, então eu vou lembrar desta!

Esteja ciente de que a partir do AngularJS 1.4 você não pode mais usar ng-options, mas você precisa usar o ng-repeat em sua tag de opção:

  

A pergunta já foi respondida (BTW, resposta muito boa e abrangente fornecida por Ben), mas eu gostaria de adicionar outro elemento para completude, o que pode ser também muito útil.

No exemplo sugerido por Ben:

  

o seguinte formulário ngOptions foi usado: select as label for value in array .

Label é uma expressão cujo resultado será o label do elemento . Nesse caso, você pode executar determinadas concatenações de strings, para ter labels de opções mais complexos.

Exemplos:

  • ng-options="item.ID as item.Title + ' - ' + item.ID for item in items" fornece labels como Title - ID
  • ng-options="item.ID as item.Title + ' (' + item.Title.length + ')' for item in items" fornece labels como Title (X) , onde X é o tamanho da string de título.

Você também pode usar filtros, por exemplo,

  • ng-options="item.ID as item.Title + ' (' + (item.Title | uppercase) + ')' for item in items" fornece labels como Title (TITLE) , onde o valor do título da propriedade Title e TITLE é o mesmo valor, mas convertido em caracteres maiúsculos.
  • ng-options="item.ID as item.Title + ' (' + (item.SomeDate | date) + ')' for item in items" fornece labels como Title (27 Sep 2015) , se o seu modelo tiver uma propriedade SomeDate

Em CoffeeScript:

 #directive app.directive('select2', -> templateUrl: 'partials/select.html' restrict: 'E' transclude: 1 replace: 1 scope: options: '=' model: '=' link: (scope, el, atr)-> el.bind 'change', -> console.log this.value scope.model = parseInt(this.value) console.log scope scope.$apply() ) 
      

Sometimes it's much easier to create your own directive...

Se você precisar de um título personalizado para cada opção, o ng-options não é aplicável. Em vez disso, use ng-repeat com opções:

  

Espero que o seguinte funcione para você.

  

Pode ser útil. As ligações nem sempre funcionam.

  

Por exemplo, você preenche o modelo de origem da lista de opções de um serviço REST. Um valor selecionado era conhecido antes de preencher a lista e foi definido. Depois de executar a solicitação REST com $ http, a opção de lista é concluída.

Mas a opção selecionada não está definida. Por razões desconhecidas, o AngularJS na execução do shadow $ digest não se associa como deveria. Eu tenho que usar o jQuery para definir o selecionado. É importante! AngularJS, na sombra, adiciona o prefixo ao valor do “valor” attr gerado pelas opções ng-repeat. Para int, é “number:”.

 $scope.issue.productId = productId; function activate() { $http.get('/product/list') .then(function (response) { $scope.products = response.data; if (productId) { console.log("" + $("#product option").length);//for clarity $timeout(function () { console.log("" + $("#product option").length);//for clarity $('#product').val('number:'+productId); }, 200); } }); }