Angular.js: Angular 1.6 se réinitialise incorrectement `<select>valeur de `ng-model`</select>

Créé le 20 janv. 2017  ·  3Commentaires  ·  Source: angular/angular.js

Remarque : pour les questions d'assistance, veuillez utiliser l'un de ces canaux: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question.

Voulez-vous demander une fonctionnalité ou signaler un bogue ?
Bogue

Quel est le comportement actuel?
Angular 1.6 réinitialise la <select> s ng-model lorsque la liste de <option> change (voir la section "Autres informations").
Angular 1.5 le préserve.

Si le comportement actuel est un bogue, veuillez fournir les étapes pour reproduire et si possible une démo minimale du problème via https://plnkr.co ou similaire (template: http://plnkr.co/edit/tpl:yBpEi4) .
Angulaire 1.6: https://plnkr.co/edit/wHc4rzy7x9PAEqQLfVQT?p=preview
Angulaire 1.5.11: https://plnkr.co/edit/e0LVMEtGP2j4JxNf8lsp?p=preview

Quel est le comportement attendu?
ng-model préserve sa valeur.

Quelle est la motivation / le cas d'utilisation pour changer le comportement?
Ce n'est pas correct.

Quelles versions d'Angular et quel navigateur / système d'exploitation sont concernés par ce problème? Veuillez également tester avec les dernières versions stable et snapshot (https://code.angularjs.org/snapshot/).
Angular 1.6.x est affecté.
Angular 1.5.x ne l'est pas.

Autres informations (par exemple, traces de pile, problèmes associés, suggestions de résolution)
Le truc, c'est qu'Angular 1.6 suit les options par son modèle et non par la options s.

Dans les extraits ci-dessus, le tableau d'options contient 2 objets: [{val: "1"}, {val: "2"}] .
ng-repeat parcourt et utilise la propriété val à la fois comme valeur d'option et titre.
vm.selected est utilisé comme ng-model de select et est initialement mis à "2".

Après avoir appuyé sur le bouton Change options je remplace le tableau d'options par celui-ci: [{val: "2"}, {val: "3"}] et Angular 1.6 réinitialise la vm.selected mais cela ne devrait pas car l'option avec la valeur 2 est toujours dans la liste.

Angular 1.5 se comporte correctement dans ce cas et la vm.selected est préservée.

Si vm.options contient des valeurs primitives, le bogue n'apparaît pas ( extrait de code ).

forms low investigation regression bug

Commentaire le plus utile

Il semble qu'il s'agissait d'un changement intentionnel dans https://github.com/angular/angular.js/commit/47c15fbcc10f118170813021e8e605ffd263ad84 : "- lorsqu'une option actuellement sélectionnée est supprimée ou que sa valeur change, le modèle est défini sur null. " mais cela ne tenait pas compte du fait que cela pourrait être cassant, ou que ngRepeat prendrait un résumé pour mettre à jour les options. C'est aussi plus facile à faire dans ngOptions car nous contrôlons la création / destruction des éléments.
Mais scheduleRender () fonctionne, yay pour @gkalpak ! Je vais voir si ça casse les tests et préparer un PR.

Tous les 3 commentaires

Cela semble être un problème valide et il casse dans 1.6.0-rc.0. Je ne sais pas pourquoi cela ne s'est pas produit auparavant, mais le problème semble être le suivant:

  1. Lorsque le tableau change, ngRepeat supprime les éléments <option> précédents.
  2. Cela provoque le <select> pour obtenir désélectionné et ngModel à la valeur null.
  3. Les nouveaux éléments sont créés et insérés par ngRepeat , mais le modelValue n'est plus 2 , donc <select> n'a aucun moyen de l'associer au nouveau <option value="2" ...> .

Une solution consiste à utiliser track by pour éviter de détruire et de recréer les éléments <option> :

<option ng-repeat="option in options track by option.val" value="option.val">...

#

d'un coup d'œil, les commits suivants sont des candidats pour avoir causé cela (mais cela pourrait être autre chose):

  • f02b707
  • 47c15fb
  • 2785ad7

#

Du haut de ma tête, je commencerais par remplacer cette ligne par scheduleRender() et voir si cela aide ...

Je suis sûr que @Narretz aura de meilleures informations: smiley:

Une solution consiste à utiliser track by pour éviter de détruire et de recréer le

Oui, je l'ai découvert aussi mais j'ai oublié de le mentionner 😏

Il semble qu'il s'agissait d'un changement intentionnel dans https://github.com/angular/angular.js/commit/47c15fbcc10f118170813021e8e605ffd263ad84 : "- lorsqu'une option actuellement sélectionnée est supprimée ou que sa valeur change, le modèle est défini sur null. " mais cela ne tenait pas compte du fait que cela pourrait être cassant, ou que ngRepeat prendrait un résumé pour mettre à jour les options. C'est aussi plus facile à faire dans ngOptions car nous contrôlons la création / destruction des éléments.
Mais scheduleRender () fonctionne, yay pour @gkalpak ! Je vais voir si ça casse les tests et préparer un PR.

Cette page vous a été utile?
0 / 5 - 0 notes