Почему AngularJS включает в себя пустую опцию?

Я работаю с AngularJS в течение последних нескольких недель, и одна вещь, которая меня действительно беспокоит, заключается в том, что даже после попытки всех перестановок или конфигурации, определенных в спецификации, http://docs.angularjs.org/api/ng.directive:select, я все еще получаю пустую опцию в качестве первого дочернего элемента select.

Здесь Джейд:

select.span9(ng-model='form.type', required, ng-options='option.value as option.name for option in typeOptions');

Здесь контроллер:

$scope.typeOptions = [
    { name: 'Feature', value: 'feature' },
    { name: 'Bug', value: 'bug' },
    { name: 'Enhancement', value: 'enhancement' }
];

Наконец, здесь создается HTML-код:

<select ng-model="form.type" required="required" ng-options="option.value as option.name for option in typeOptions" class="span9 ng-pristine ng-invalid ng-invalid-required">
    <option value="?" selected="selected"></option>
    <option value="0">Feature</option>
    <option value="1">Bug</option>
    <option value="2">Enhancement</option>
</select>

Что мне нужно сделать, чтобы избавиться от него?

P.S.: Вещи тоже работают без этого, но это выглядит странно, если вы используете select2 без множественного выбора.

Ответ 1

Пустое option генерируется, когда значение, на которое ссылается ng-model, не существует в наборе параметров, переданных в ng-options. Это происходит, чтобы предотвратить случайный выбор модели: AngularJS может видеть, что исходная модель либо undefined, либо нет в наборе параметров и не хочет самостоятельно определять значение модели.

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

$scope.form.type = $scope.typeOptions[0].value;

Вот jsFiddle: http://jsfiddle.net/MTfRD/3/

Короче: пустая опция означает, что не выбрана допустимая модель (по действию я имею в виду: из набора параметров). Вам нужно выбрать допустимое значение модели, чтобы избавиться от этой пустой опции.

Ответ 2

Если вы хотите получить начальное значение, см. ответ @pkozlowski.opensource, который FYI также может быть реализован в представлении (а не в контроллере) с помощью ng-init:

<select ng-model="form.type" required="required" ng-init="form.type='bug'"
  ng-options="option.value as option.name for option in typeOptions" >
</select>

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

<select ng-model="form.type" required="required"
  ng-options="option.value as option.name for option in typeOptions" >
    <option style="display:none" value="">select a type</option>
</select>

Ответ 3

Angular < 1.4

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

<select ng-options="option.value as option.name for option in typeOptions">
    <option value="" ng-if="false"></option>
</select>

Почему ng-if и не ng-hide? Поскольку вы хотите, чтобы селектора css, предназначенные для первой опции внутри, выбирали целевую "реальную" опцию, а не та, которая скрыта. Это становится полезным, когда вы используете транспортир для тестирования e2e и (по какой-либо причине) вы используете by.css() для выбора опций выбора.

Angular >= 1.4

Из-за рефакторинга директив select и options использование ng-if больше не является жизнеспособным вариантом, поэтому вам нужно перейти на ng-show="false", чтобы он снова работал.

Ответ 4

Может быть полезно кому-то:

Если вы хотите использовать простые опции вместо ng-options, вы можете сделать следующее:

<select ng-model="sortorder" ng-init="sortorder='publish_date'">
  <option value="publish_date">Ascending</option>
  <option value="-publish_date">Descending</option>
</select>

Задайте модель встроенной. Используйте ng-init, чтобы избавиться от пустой опции

Ответ 5

Что-то подобное произошло со мной и было вызвано обновлением до angular 1.5. ng-init похоже, анализируется для типа в более новых версиях Angular. В более раннем angular ng-init="myModelName=600" будет отображаться опция со значением "600", то есть <option value="600">First</option>, но в angular 1.5 она не найдет этого, поскольку, похоже, ожидает найти параметр со значением 600, т.е. <option value=600>First</option>. angular затем вставляет случайный первый элемент:

<option value="? number:600 ?"></option>

Angular < 1.2.x

<select ng-model="myModelName" ng-init="myModelName=600">
  <option value="600">First</option>
  <option value="700">Second</option>
</select>

Angular > 1.2

<select ng-model="myModelName" ng-init="myModelName='600'">
  <option value="600">First</option>
  <option value="700">Second</option>
</select>

Ответ 6

Среди множества ответов здесь я решил, что перережу решение, которое сработало для меня, и встретило все следующие условия:

  • предоставил заполнитель/приглашение, когда ng-модель является ложной (например, "- select region--" w. value="")
  • когда значение ng-модели ложно, и пользователь открывает раскрывающийся список опций, выбирается местозаполнитель (другие решения, упомянутые здесь, делают первый вариант выбранным, который может вводить в заблуждение)
  • позволяют пользователю отменить правильное значение, существенно выбрав значение ложности/значения по умолчанию

введите описание изображения здесь

код

<select name="market_vertical" ng-model="vc.viewData.market_vertical"
    ng-options="opt as (opt | capitalizeFirst) for opt in vc.adminData.regions">

    <option ng-selected="true" value="">select a market vertical</option>
</select>

ЦСИ

оригинал q & a - fooobar.com/questions/13576/...

Ответ 7

Быстрое решение:

select option:empty { display:none }

Надеюсь, это поможет кому-то. В идеале выбранный ответ должен быть подходом, но если в случае невозможности он должен работать как патч.

Ответ 8

Да ng-model создаст пустое значение параметра, когда свойство ng-model undefined. Мы можем избежать этого, если мы назначим объект ng-model

Пример

angular кодирование

$scope.collections = [
    { name: 'Feature', value: 'feature' }, 
    { name: 'Bug', value: 'bug' }, 
    { name: 'Enhancement', value: 'enhancement'}
];

$scope.selectedOption = $scope.collections[0];


<select class='form-control' data-ng-model='selectedOption' data-ng-options='item as item.name for item in collections'></select>

Важное примечание:

Назначить объект массива как $scope.collections [0] или $scope.collections [1] в ng-model, не использовать свойства объекта. если вы получаете значение опции выбора с сервера, используя функцию обратного вызова, назначьте объект ng-model

ПРИМЕЧАНИЕ из документа Angular

Примечание: ngModel сравнивается по ссылке, а не по значению. Это важно при привязке к массиву объектов. см. пример http://jsfiddle.net/qWzTb/

Я много раз пытался найти его.

Ответ 9

Хотя оба ответа @pkozlowski.opensource и @Mark верны, я хотел бы поделиться своей измененной версией, где всегда выбираю первый элемент в списке, независимо от его значения:

<select ng-options="option.value as option.name for option in typeOptions" ng-init="form.type=typeOptions[0].value">
</select>

Ответ 10


Я столкнулся с той же проблемой. Если вы публикуете форму angular с обычной почтой, вы столкнетесь с этой проблемой, так как angular не позволяет устанавливать значения для параметров в том виде, в котором вы использовали. Если вы получите значение "form.type", то вы найдете нужное значение. Вы должны опубликовать объект angular, это не сообщение формы.

Ответ 11

Хорошо, на самом деле ответ прост: если опция Angular не распознана, она содержит тупую. Что вы делаете неправильно, когда вы используете ng-options, он читает объект, скажем [{ id: 10, name: test }, { id: 11, name: test2 }] right?

Это то, что должно оценивать ваше значение модели как равное, например, вы хотите, чтобы выбранное значение было равным 10, вам нужно установить свою модель на значение, подобное { id: 10, name: test }, чтобы выбрать 10, поэтому оно НЕ будет создавать это мусор.

Надеюсь, что это поможет всем понять, мне было тяжело попробовать:)

Ответ 12

Я использую Angular 1.4x, и я нашел этот пример, поэтому я использовал ng-init для установки начального значения в select:

<select ng-init="foo = foo || items[0]" ng-model="foo" ng-options="item as item.id for item in items"></select>

Ответ 13

Простое решение - установить опцию с пустым значением "". Я обнаружил, что это исключает дополнительную опцию undefined.

Ответ 14

Это сработало для меня

<select ng-init="basicProfile.casteId" ng-model="basicProfile.casteId" class="form-control">
     <option value="0">Select Caste....</option>
     <option data-ng-repeat="option in formCastes" value="{{option.id}}">{{option.casteName}}</option>
 </select>

Ответ 15

Это прекрасно работает

<select ng-model="contact.Title" ng-options="co for co in['Mr.','Ms.','Mrs.','Dr.','Prof.']">
    <option style="display:none" value=""></option>
</select>

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

<select ng-model="contact.Title" ng-options="co for co in['Mr.','Ms.','Mrs.','Dr.','Prof.']">
    <option style="display:none" value="">select an option...</option>
</select>

и это даст вам select and option перед выбором, но после его выбора он исчезнет, ​​и он не появится в раскрывающемся списке.

Ответ 16

Это решение работает для меня:

<select ng-model="mymodel">    
   <option ng-value="''" style="display:none;" selected>Country</option>
   <option value="US">USA</option>
</select>

Ответ 17

Попробуйте это в своем контроллере в том же порядке:

$scope.typeOptions = [
    { name: 'Feature', value: 'feature' }, 
    { name: 'Bug', value: 'bug' }, 
    { name: 'Enhancement', value: 'enhancement' }
];
$scope.form.type = $scope.typeOptions[0];

Ответ 18

Вот исправление:

для образца данных типа:

financeRef.pageCount = [{listCount:10,listName:modelStrings.COMMON_TEN_PAGE},    
{listCount:25,listName:modelStrings.COMMON_TWENTYFIVE_PAGE},
{listCount:50,listName:modelStrings.COMMON_FIFTY_PAGE}];

Опция выбора должна быть такой: -

<select ng-model="financeRef.financeLimit" ng-change="financeRef.updateRecords(1)" 
class="perPageCount" ng-show="financeRef.showTable" ng-init="financeRef.financeLimit=10"
ng-options="value.listCount as value.listName for  value in financeRef.pageCount"
></select>

Точка, когда мы пишем value.listCount как value.listName, автоматически заполняет текст в value.listName, но значение выбранного параметра равно value.listCount, хотя значения my show normal 0,1,2.. и т.д.

В моем случае financeRef.financeLimit на самом деле захватывает value.listCount, и я могу динамически манипулировать контроллером.

Ответ 19

Я хотел бы добавить, что если начальное значение происходит от привязки от какого-либо родительского элемента или 1.5 компонента, убедитесь, что соответствующий тип передан. При использовании @ в привязке передаваемая переменная будет строкой, и если, например, есть варианты. целые числа, тогда появится пустая опция.

Либо правильно проанализировать значение в init, либо привязать его к <, а не @ (менее рекомендуется для производительности, если это необходимо).

Ответ 20

Простое решение

<select ng-model='form.type' required><options>
<option ng-repeat="tp in typeOptions" ng-selected="    
{{form.type==tp.value?true:false}}" value="{{tp.value}}">{{tp.name}}</option>

Ответ 21

Измельчить решение с помощью jQuery, если вы не контролируете параметры

HTML:

<select id="selector" ng-select="selector" data-ng-init=init() >
...
</select>

JS:

$scope.init = function () {
    jQuery('#selector option:first').remove();
    $scope.selector=jQuery('#selector option:first').val();
}

Ответ 22

Если вы используете ng-init свою модель для решения этой проблемы:

<select ng-model="foo" ng-app ng-init="foo='2'">

Ответ 23

У меня была та же проблема, i (удаленная "ng-model" ) изменила это:

<select ng-model="mapayear" id="mapayear" name="mapayear" style="  display:inline-block !important;  max-width: 20%;" class="form-control">
  <option id="removable" hidden> Selecione u </option>
    <option selected ng-repeat="x in anos" value="{{ x.ano }}">{{ x.ano }}
</option>
</select>

:

<select id="mapayear" name="mapayear" style="  display:inline-block !important;  max-width: 20%;" class="form-control">
  <option id="removable" hidden> Selecione u </option>
    <option selected ng-repeat="x in anos" value="{{ x.ano }}">{{ x.ano }}
</option>
</select>

теперь он работает, но в моем случае это было причиной того, что Ive удалил эту область из ng.controller, проверьте, не выполнил ли u то же самое.

Ответ 25

Единственное, что сработало для меня, это использовать track by в ng-options, например:

 <select class="dropdown" ng-model="selectedUserTable" ng-options="option.Id as option.Name for option in userTables track by option.Id">

Ответ 26

Обратитесь к примеру из документации angularjs, как преодолеть эти проблемы.

  1. Перейдите по ссылке на эту документацию здесь
  2. Найти 'привязку выбора к нестроковому значению с помощью синтаксического анализа/форматирования ngModel'
  3. Там вы можете видеть, что директива под названием convertToNumber"решает проблему.

Меня устраивает. Также можно посмотреть, как это работает здесь

Ответ 27

Мы можем использовать CSS, чтобы скрыть первый вариант, но он не будет работать в IE 10, 11. Лучший способ - удалить элемент с помощью Jquery. Это решение работает для основных браузеров, протестированных в Chrome и IE10, 11

Также, если вы используете angular, иногда работает setTimeout

$scope.RemoveFirstOptionElement = function (element) {
    setTimeout(function () {
        $(element.children()[0]).remove();
    }, 0);
};