AngularJS - выпадающий список ng-option не устанавливает значение ng-model при выборе False

У меня есть элемент <select>, который использует ng-options для создания списка выбора и, надеюсь, устанавливает для выбранного значение ng-model. Вот мой html:

<td style="text-align:center">
    <ng-form name="IsTobaccoForm">
        <select name="Input" required ng-model="dep.IsTobacco" ng-options="item.value as item.text for item in yesNoList"></select>{{dep.IsTobacco}}
        <span class="alert-error" ng-show="IsTobaccoForm.Input.$error.required"><strong>*Required</strong></span>
    </ng-form>
</td>

Мой контроллер содержит следующий код:

$scope.yesNoList = [{ value: true, text: 'Y' }, { value: false, text: 'N'}];

Если значение IsTobacco элемента равно true, значение установлено правильно и все в порядке. Однако, если оно ложно, появляется требуемая ошибка, даже если {{dep.IsTobacco}} отображается как ложное. Действительно странная часть заключается в том, что если я изменяю выбранный элемент в списке на true, он работает нормально, однако, если я устанавливаю для него значение false, в список добавляется новый пустой элемент, и этот пустой элемент выбирается.

Если кажется, что проблемы не заключаются в строках, опубликованных выше, я с удовольствием опубликую больше кода.

Спасибо!

EDIT: я также использовал отладчик Chrome и увидел, что когда данные инициировались в Angular, значение IsTobacco было равно false.

Редактировать 2: Если кто-то, кто просматривает это, не знаком с AngularJS, я определенно рекомендую прочитать эти 2 статьи: часть 1 & часть 2. Это обзор форм AngularJS.


person PFranchise    schedule 18.06.2013    source источник
comment
По какой-то причине (возможно, связанной с флажками?) значение false интерпретируется как отсутствие ngModel при использовании с required - github.com/angular/angular.js/issues/2436. Одним из обходных путей может быть использование вместо этого строки «true» и «false».   -  person Dan    schedule 18.06.2013
comment
@sh0ber о боже. Это нехорошо ха-ха. Спасибо за информацию об этом. Я заставлял себя не взламывать обходной путь, полагая, что причиной проблемы было отсутствие у меня знаний об angular.   -  person PFranchise    schedule 18.06.2013
comment
Ничего страшного, я сам этого не осознавал. Вероятно, так быть не должно, учитывая, что флажки могут принимать атрибуты ng-true-value и ng-false-value. Но я предполагаю, что это было либо так, либо принудительно использовать неистинные и неложные значения для этих атрибутов для каждого флажка, и это был лучший выбор.   -  person Dan    schedule 18.06.2013
comment
Да, это определенно имеет смысл. Я не учел последствия использования ng-options с флажками.   -  person PFranchise    schedule 18.06.2013
comment
Опубликовано как ответ сейчас :)   -  person Dan    schedule 18.06.2013


Ответы (1)


Это происходит потому, что значение false интерпретируется как отсутствие ngModel при использовании с required. Как обсуждалось здесь, рассмотрите этот отрывок из исходного кода Angular:

var validator = function(value) {
    if (attr.required && (isEmpty(value) || value === false)) {
        ctrl.$setValidity('required', false);

Если обязательный атрибут есть и его значение равно false, он не проходит проверку. Вероятно, это сделано намеренно, чтобы упростить проверку необходимых флажков, и в этом случае значение по умолчанию для неотмеченных — false.

Возможно, в этом нет необходимости, учитывая, что флажки могут принимать атрибуты ng-true-value и ng-false-value, но я предполагаю, что нужно было либо сделать это, либо принудительно использовать значения не-true и не-false для этих атрибутов для каждого флажка, и это было лучший выбор.

Одним из обходных путей может быть использование вместо этого строк «true» и «false».

person Dan    schedule 18.06.2013
comment
sh0ber уже упоминал об использовании флажков, но я чувствую, что это следует подчеркнуть еще больше. Я изменил свой код, чтобы использовать «Да» и «Нет», а затем понял, что я взламывал, когда мне это не нужно. Используйте флажки. - person Jack; 29.12.2014