Angular.js: Angular 1.6 неправильно сбрасывает `<select>значение `ng-model`</select>

Созданный на 20 янв. 2017  ·  3Комментарии  ·  Источник: angular/angular.js

Примечание . Для вопросов поддержки используйте один из этих каналов: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question.

Вы хотите запросить функцию или сообщить об ошибке ?
Ошибка

Каково текущее поведение?
Angular 1.6 сбрасывает значение <select> s ng-model при изменении списка <option> s (см. Раздел «Другая информация»).
Angular 1.5 сохраняет это.

Если текущее поведение является ошибкой, предоставьте шаги для воспроизведения и, если возможно, минимальную демонстрацию проблемы через https://plnkr.co или аналогичный (шаблон: http://plnkr.co/edit/tpl:yBpEi4) .
Угловой 1.6: https://plnkr.co/edit/wHc4rzy7x9PAEqQLfVQT?p=preview
Угловой 1.5.11: https://plnkr.co/edit/e0LVMEtGP2j4JxNf8lsp?p=preview

Какое поведение ожидается?
ng-model сохраняет свою ценность.

Какова мотивация / вариант использования для изменения поведения?
Это не правильно.

Какие версии Angular и какой браузер / ОС подвержены этой проблеме? Также проверьте последнюю стабильную версию и версию моментального снимка (https://code.angularjs.org/snapshot/).
Angular 1.6.x затронут.
Angular 1.5.x - нет.

Другая информация (например, трассировки стека, связанные проблемы, предложения по исправлению)
Дело в том, что Angular 1.6 отслеживает параметры по своей модели, а не по значению options s.

В приведенных выше фрагментах массив параметров содержит 2 объекта: [{val: "1"}, {val: "2"}] .
ng-repeat выполняет итерацию по ним и использует свойство val как значение параметра и заголовок.
vm.selected используется как значение ng-model select и изначально установлено на "2".

После нажатия кнопки Change options я заменяю массив параметров следующим: [{val: "2"}, {val: "3"}] и Angular 1.6 сбрасывает значение vm.selected но этого не должно быть, потому что параметр со значением 2 равен все еще в списке.

Angular 1.5 в этом случае ведет себя правильно, и значение vm.selected сохраняется.

Если vm.options содержит примитивные значения, ошибка не появляется ( фрагмент ).

forms low investigation regression bug

Самый полезный комментарий

Похоже, это было намеренное изменение в https://github.com/angular/angular.js/commit/47c15fbcc10f118170813021e8e605ffd263ad84 : "- когда выбранный в данный момент параметр удаляется или изменяется его значение, для модели устанавливается значение null. " но при этом не принималось во внимание то, что это могло сломаться или что ngRepeat будет использовать дайджест для обновления параметров. Это также проще сделать в ngOptions, потому что мы контролируем создание / уничтожение элементов.
Но scheduleRender () работает, ура для

Все 3 Комментарий

Похоже на серьезную проблему, и она ломается в 1.6.0-rc.0. Не уверен, почему этого не произошло раньше, но проблема, похоже, в следующем:

  1. При изменении массива ngRepeat удаляет предыдущие элементы <option> .
  2. Это приводит к тому, что <select> не выбирается, а ngModel устанавливается в значение null.
  3. Новые элементы создаются и вставляются с помощью ngRepeat , но modelValue больше не 2 , поэтому <select> не может связать его с новым <option value="2" ...> .

Обходной путь - использовать track by чтобы избежать разрушения и воссоздания элементов <option> :

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

#

на первый взгляд, следующие коммиты являются кандидатами на то, чтобы вызвать это (но это может быть что-то еще):

  • f02b707
  • 47c15fb
  • 2785ad7

#

Я бы начал с того, что заменил эту строку на scheduleRender() и посмотрел, поможет ли это ...

Я уверен, что @Narretz сможет лучше понять: smiley:

Обходной путь - использовать отслеживание, чтобы избежать разрушения и воссоздания

Да, тоже узнал, но забыл упомянуть 😏

Похоже, это было намеренное изменение в https://github.com/angular/angular.js/commit/47c15fbcc10f118170813021e8e605ffd263ad84 : "- когда выбранный в данный момент параметр удаляется или изменяется его значение, для модели устанавливается значение null. " но при этом не принималось во внимание то, что это могло сломаться или что ngRepeat будет использовать дайджест для обновления параметров. Это также проще сделать в ngOptions, потому что мы контролируем создание / уничтожение элементов.
Но scheduleRender () работает, ура для

Была ли эта страница полезной?
0 / 5 - 0 рейтинги