Angular.js: Angular 1.6 redefine incorretamente `<select>valor `ng-model`</select>

Criado em 20 jan. 2017  ·  3Comentários  ·  Fonte: angular/angular.js

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 ).

forms low investigation regression bug

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.

Todos 3 comentários

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:

  1. Quando a matriz muda, ngRepeat remove os elementos <option> .
  2. Isso faz com que <select> seja desmarcado e ngModel seja definido como nulo.
  3. Os novos itens são criados e inseridos por 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):

  • f02b707
  • 47c15fb
  • 2785ad7

#

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.

Esta página foi útil?
0 / 5 - 0 avaliações