Angular добавляет странные опции в элемент select при установке значения модели

У меня есть элемент select, определенный как таковой:

<select name="country_id" id="country_id" required="required" ng-model="newAddressForm.country_id">
    <option value="">Select Country</option>
    <option ng-repeat="country in countries" value="{{country.id}}">{{country.name}}</option>
</select>

Все работает нормально, когда я не устанавливаю никаких значений в директиве, содержащей этот элемент select. Но когда я делаю что-то вроде newAddressForm.country_id = 98вместо выбора опции со значением 98 Angular вставляет новый в верхнюю часть элемента select, например, так:

<option value="? string:98 ?"></option>

Что дает? Что это за формат и почему это происходит? Обратите внимание, что если я сделаю console.log(newAddressForm.country_id) в директиве я получаю нормальный "98"это просто странно в сгенерированном HTML.

Изменить: обновление ситуации. Перешли на использование ng-select, но проблема сохраняется.

Странный элемент больше не появляется, НО, теперь есть еще один элемент в верхней части, который имеет только знак вопроса ? в качестве значения, а не метки.

Вот из того, что я собрал, Angular's "none selected" вариант. Я все еще не понимаю, почему он не выберет опцию, которую я говорю, чтобы выбрать, хотя.

дела newAddressForm.country_id = 98 до сих пор не дает результатов. Это почему?

8 ответов

Решение

Angular не устанавливает значение элемента select на фактические значения вашего массива и выполняет некоторые внутренние операции для управления привязкой области. Смотрите первый комментарий Марка Райкока по этой ссылке:

https://docs.angularjs.org/api/ng/directive/select

Когда пользователь выбирает один из параметров, Angular использует индекс (или ключ) для поиска значения в массиве (или объекте) - это искомое значение является тем, для которого установлена ​​модель. (Таким образом, модель не установлена ​​на значение, которое вы видите в HTML! Это вызывает много путаницы.)

Я не совсем уверен, используя ng-repeat это лучший вариант.

Используя следующий синтаксис с ng-options решил эту проблему для меня:

<select name="country_id" id="country_id" required="required" ng-model="newAddressForm.country_id" ng-options="country.id as country.name for country in countries">
  <option value="">Select Country</option>
</select>

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

Вы не должны использовать это:

{ value: 0, name: "Pendiente" },
{ value: 1, name: "Em andamento" },
{ value: 2, name: "Erro" },
{ value: 3, name: "Enviar email" },
{ value: 4, name: "Enviado" }

Это правильный путь:

{ value: "0", name: "Pendiente" },
{ value: "1", name: "Em andamento" },
{ value: "2", name: "Erro" },
{ value: "3", name: "Enviar email" },
{ value: "4", name: "Enviado" }

Если у вас есть хотя бы одна запись, которая не использует "", вы получите это? значение опции.

Когда вы присваиваете значение некоторому элементу select, AngularJS ищет предоставленное значение в атрибуте value тегов option в этом элементе select. Но проблема в том, что AngularJS делает сравнение на основе типов. Поэтому, если значения в тегах параметров являются строками (что обычно имеет место), а переменная, которую вы связываете с помощью ng-model, является числом, AngularJS не может найти соответствующий элемент параметра и, следовательно, создает свой собственный элемент, подобный этому:

<option value="? integer:10 ?"></option>

Решение, связывая себя, преобразовывает его в соответствующий тип.

В этом случае решением будет связать целое число

<select name="country_id" id="country_id" required="required" ng-model="parseInt(newAddressForm.country_id)">
<option value="">Select Country</option>
<option ng-repeat="country in countries" value="{{country.id}}">{{country.name}}</option>
</select>

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

<select ... ng-model="newAddressForm.country_id.toString()" >

Я столкнулся с этой же проблемой ранее этим вечером, когда увидел, что опция выбора появилась первой в моем списке, хотя я ее явно не создавал. Я заполнял список опций выбора в моем контроллере и использовал тот же синтаксис ng-options, который был упомянут выше jessedvrs (за исключением того, что я также вставлял опцию "выбрать опцию" по умолчанию в контроллер вместо того, чтобы отмечать ее в HTML, как он было).

По какой-то причине в списке выбора всегда показывался бы дополнительный параметр с нулевым индексом со значением "?", Но когда я изменил способ заполнения параметра по умолчанию в контроллере, эта проблема исчезла. Я заполнял опции выбора, делая вызов API, заполняя их внутри обещания. Я сделал ошибку, также заполнив свой вариант "выбрать опцию" по умолчанию, как первое, что я сделал в этом обещании, но когда я сделал это вместо обещания (до вызова API), параметры выбора заполнили путь Я хотел их.

Я думаю, что опция jessedvrs - это одно из решений проблемы (установка опции по умолчанию в разметке HTML), но если вы предпочитаете вместо этого заполнять свои опции в javascript, я бы по-прежнему предлагал установить опцию по умолчанию, прежде чем делать какие-либо вызовы API или процессы, которые все еще могут выполняться во время визуализации HTML.

Используйте " track by 'value' " в конце ваших ng-параметров:D

как пример ниже:

ng-options = "country.id как country.name для страны в странах, отслеживаемых по country.id"

При вводе данных в переменную области видимости мы можем использовать следующий код

$scope.enquiryLocationRow.push({'location': EnqLocation.location, 'state_id': Number(EnqLocation.state_id), 'country_id': Number(EnqLocation.country_id)});

это решило мою проблему

vm.kanoonCourses — массив объектов, vm.courses — массив строк:

      <table class="table table-hover">
    <tr style="font-weight: bold; background-color: #dfedf8;">
        <td>index</td>
        <td>course in our system</td>
        <td>course in outside system</td>
    </tr>
    <tr ng-repeat="course in vm.courses">
        <td style="vertical-align: middle;">{{$index+1|persianNumber}}</td>
        <td style="vertical-align: middle;">{{course.CourseTitle}}</td>
        <td>
            <select  
                ng-model="course.KanoonCourseTitle"
                ng-options="option as option for option in vm.kanoonCourses">
            </select>
        </td>
    </tr>
</table>
Другие вопросы по тегам