Observação : para perguntas de suporte, use um destes canais: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question.
Você quer solicitar um recurso ou relatar um bug ?
Inseto
Qual é o comportamento atual?
O Angular 1.6 redefine o <select>
s ng-model
quando a lista <option>
s muda (consulte a seção "Outras informações").
O Angular 1.5 o preserva.
Se o comportamento atual for um bug, forneça as etapas para reproduzir e, se possível, uma demonstração mínima do problema via https://plnkr.co ou semelhante (modelo: http://plnkr.co/edit/tpl:yBpEi4) .
Angular 1.6: https://plnkr.co/edit/wHc4rzy7x9PAEqQLfVQT?p=preview
Angular 1.5.11: https://plnkr.co/edit/e0LVMEtGP2j4JxNf8lsp?p=preview
Qual é o comportamento esperado?
ng-model
preserva seu valor.
Qual é a motivação / caso de uso para mudar o comportamento?
Não é correto.
Quais versões do Angular e quais navegadores / sistemas operacionais são afetados por esse problema? Teste também com as versões mais recentes estáveis e instantâneas (https://code.angularjs.org/snapshot/).
Angular 1.6.x é afetado.
Angular 1.5.x não é.
Outras informações (por exemplo, rastreamentos de pilha, problemas relacionados, sugestões de como corrigir)
O fato é que o Angular 1.6 rastreia as opções por seu modelo e não pelo options
s.
Nos trechos acima, o array de opções contém 2 objetos: [{val: "1"}, {val: "2"}]
.
ng-repeat
itera através deles e usa val
propriedade como valor de opção e título.
vm.selected
é usado como valor de seleção ng-model
e é inicialmente definido como "2".
Depois de pressionar o botão Change options
, substituo o array de opções por este: [{val: "2"}, {val: "3"}]
e o Angular 1.6 redefine o vm.selected
mas não deveria, porque a opção com o valor 2
é ainda na lista.
O Angular 1.5 se comporta corretamente neste caso e o vm.selected
é preservado.
Se vm.options
contém valores primitivos, o bug não aparece ( fragmento ).
Parece um problema válido e falha em 1.6.0-rc.0. Não sei por que isso não aconteceu antes, mas o problema parece ser este:
ngRepeat
remove os elementos <option>
.<select>
seja desmarcado e ngModel
seja definido como nulo.ngRepeat
, mas o modelValue não é mais 2
, então <select>
não tem como associá-lo ao novo <option value="2" ...>
.Uma solução alternativa é usar track by
para evitar destruir e recriar os elementos <option>
:
<option ng-repeat="option in options track by option.val" value="option.val">...
de uma olhada rápida, os seguintes commits são candidatos a terem causado isso (mas poderia ser outra coisa):
Pensando bem, eu começaria substituindo esta linha por scheduleRender()
e veria se isso ajuda ...
Tenho certeza de que @Narretz terá alguns insights melhores: smiley:
Uma solução alternativa é usar track by para evitar destruir e recriar o
Sim, também descobri, mas esqueci de mencionar 😏
Parece que esta foi uma alteração intencional em https://github.com/angular/angular.js/commit/47c15fbcc10f118170813021e8e605ffd263ad84 : "- quando uma opção atualmente selecionada é removida ou seu valor é alterado, o modelo é definido como nulo. " mas isso não levou em consideração que isso pode estar quebrado, ou que o ngRepeat levaria um resumo para atualizar as opções. Também é mais fácil de fazer em ngOptions porque controlamos a criação / destruição de elementos.
Mas scheduleRender () funciona, yay para @gkalpak ! Vou ver se quebra os testes e preparo um PR.
Comentários muito úteis
Parece que esta foi uma alteração intencional em https://github.com/angular/angular.js/commit/47c15fbcc10f118170813021e8e605ffd263ad84 : "- quando uma opção atualmente selecionada é removida ou seu valor é alterado, o modelo é definido como nulo. " mas isso não levou em consideração que isso pode estar quebrado, ou que o ngRepeat levaria um resumo para atualizar as opções. Também é mais fácil de fazer em ngOptions porque controlamos a criação / destruição de elementos.
Mas scheduleRender () funciona, yay para @gkalpak ! Vou ver se quebra os testes e preparo um PR.