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

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

вот Джейд:

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>

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

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

25 ответов


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

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

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

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

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


Если вам нужно начальное значение, см. @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>

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

<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>

Угловое

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

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

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

угловые >= 1.4

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


может быть полезно для кого-то:

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

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

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


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

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

enter image description here

код

<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>

src

исходный вопрос& - https://stackoverflow.com/a/32880941/1121919


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

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

Угловое

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

угловые > 1.2

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

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

select option:empty { display:none }

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


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

пример

угловое кодирование

$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.коллекции[0] или $scope.коллекции[1] для ng-модели не используйте свойства объекта. если вы получаете select option value от сервера, используя функцию обратного вызова, назначьте объект ng-model

Примечание. из углового документа

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

Я пробовал много раз, наконец я нашел его.


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

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


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


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

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

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


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

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

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


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

<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>

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

<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 перед выбором, но после выбора он исчезнет, и он не будет отображаться в раскрывающемся списке.


попробуйте это в вашем контроллере, в том же порядке:

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

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

для выборки данных, таких как :

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 as value.listName, он автоматически заполняет текст в value.listName но значение выбранного параметра value.listCount хотя значения мои показывают нормальные 0,1,2 .. и так далее !!!

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


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

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


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

<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>


решение grind с 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();
}

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

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

у меня была такая же проблема, я (удалил "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.контроллер, проверьте, не сделал ли ты то же самое.


Привет у меня были некоторые мобильные ссылки jQUery, и я удалил их. С jQuery mobile любые из вышеперечисленных исправлений не работали для меня. (Это здорово, если кто-то может объяснить конфликт между jQuery Mobile и Angular JS )

https://guntucomputerhacks.blogspot.com.au/2017/10/angular-js-drop-down-first-options-vs.html


единственное, что сработало для меня, это использование 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">


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

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