Почему AngularJS включает пустую опцию в select?
Я работал с 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>
Что мне нужно сделать, чтобы избавиться от этого?
PS: без этого все работает, но это выглядит странно, если вы используете 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>
Если вам не нужно начальное значение, "в элемент может быть вложен один жестко запрограммированный элемент со значением, равным пустой строке. Этот элемент будет представлять нулевую или" не выбранную "опцию":
<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>
Угловой < 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>
Почему нг-если и не нг-скрыть? Поскольку вы хотите, чтобы селекторы css были нацелены на первый вариант внутри, выберите таргетинг на "реальный" вариант, а не тот, который скрыт. Это становится полезным, когда вы используете транспортир для тестирования e2e и (по любой причине) вы используете by.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>
Установите модель в линию. Используйте ng-init, чтобы избавиться от пустой опции
Нечто подобное происходило и со мной и было вызвано обновлением до угловой версии 1.5.ng-init
Кажется, в новых версиях 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>
Угловой < 1.2.x
<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>
Среди множества ответов здесь я решил опубликовать решение, которое работает для меня, и выполнить все следующие условия:
- предоставил заполнитель / подсказку, когда ng-модель ложна (например, "--select region--" w.
value=""
) - когда значение ng-model является ложным, и пользователь открывает раскрывающийся список параметров, выбирается местозаполнитель (другие решения, упомянутые здесь, делают первый параметр выбранным, что может вводить в заблуждение)
- разрешить пользователю отменить выбор допустимого значения, по существу, снова выбрав ложное значение / значение по умолчанию
код
<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>
ЦСИ
оригинальные вопросы и ответы - /questions/47498254/angularjs-i-select-vyibrannyie-po-umolchaniyu-parametryi-udalenyi/47498278#47498278
Быстрое решение:
select option:empty { display:none }
Надеюсь, это поможет кому-то. В идеале, выбранный ответ должен быть подходом, но если в случае, если это невозможно, то должен работать как патч.
Да, ng-модель создаст пустое значение опции, когда свойство ng-модели неопределено. Мы можем избежать этого, если мы назначим объект для ng-модели
пример
угловое кодирование
$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-модели, не используйте свойства объекта. если вы получаете значение параметра select с сервера, используя функцию обратного вызова, присвойте объект ng-модели
ПРИМЕЧАНИЕ от углового документа
Примечание: 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 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>
Я столкнулся с той же проблемой. Если вы публикуете угловую форму с обычной публикацией, то вы столкнетесь с этой проблемой, так как угловая форма не позволяет вам устанавливать значения для параметров, которые вы использовали. Если вы получите значение "form.type", то вы найдете правильное значение. Вы должны опубликовать угловой объект сам, а не форму сообщения.
Простое решение - установить опцию с пустым значением ""
Я обнаружил, что это исключает дополнительную неопределенную опцию.
Хорошо, на самом деле ответ очень прост: когда есть опция, не распознаваемая Angular, она включает тусклую. Что вы делаете неправильно, когда вы используете ng-options, он читает объект, скажем [{ id: 10, name: test }, { id: 11, name: test2 }] right?
Это то, чем должно быть значение вашей модели, чтобы оценить его как равное, скажем, вы хотите, чтобы выбранное значение было равно 10, вам нужно установить для вашей модели значение, подобное { id: 10, name: test }
выбрать 10, поэтому он не будет создавать этот мусор.
Надеюсь, это поможет всем понять, я очень старался:)
Это решение работает для меня:
<select ng-model="mymodel">
<option ng-value="''" style="display:none;" selected>Country</option>
<option value="US">USA</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
перед выбором, но после выбора он исчезнет и не будет отображаться в раскрывающемся списке.
Это сработало для меня
<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>
Вот исправление:
для образца данных, таких как:
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
хотя значения мои показывают нормальные 0,1,2 .. и тд!!!
В моем случае financeRef.financeLimit
на самом деле хватает value.listCount
и я могу делать свои манипуляции в контроллере динамически.
У меня была такая же проблема, я (убрал "ng-модель") изменил это:
<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>
теперь это работает, но в моем случае это было причиной того, что я удалил эту область из ng.controller, проверьте, не делали ли вы то же самое.
Если вы используете ng-init вашу модель для решения этой проблемы:
<select ng-model="foo" ng-app ng-init="foo='2'">
Простое решение
<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>
Решение для измельчения с помощью jQuery, когда у вас нет контроля над опциями
HTML:
<select id="selector" ng-select="selector" data-ng-init=init() >
...
</select>
ЯШ:
$scope.init = function () {
jQuery('#selector option:first').remove();
$scope.selector=jQuery('#selector option:first').val();
}
Попробуйте это в вашем контроллере, в том же порядке:
$scope.typeOptions = [
{ name: 'Feature', value: 'feature' },
{ name: 'Bug', value: 'bug' },
{ name: 'Enhancement', value: 'enhancement' }
];
$scope.form.type = $scope.typeOptions[0];
Единственное, что сработало для меня, это использование 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">
Привет, у меня были ссылки на jQUery для мобильных устройств, и я удалил их. С jQuery mobile у меня не работало ни одно из вышеперечисленных исправлений. (Здорово, если кто-то может объяснить конфликт между jQuery Mobile и Angular JS)
https://guntucomputerhacks.blogspot.com.au/2017/10/angular-js-drop-down-first-options-vs.html
Мы можем использовать CSS, чтобы скрыть первый вариант, но он не будет работать в IE 10, 11. Лучший способ - удалить элемент с помощью JQuery. Это решение работает для основных браузеров, протестированных в Chrome и IE10, 11.
Также, если вы используете angular, иногда работает setTimeout
$scope.RemoveFirstOptionElement = function (element) {
setTimeout(function () {
$(element.children()[0]).remove();
}, 0);
};
Я хотел бы добавить, что если начальное значение исходит из привязки какого-либо родительского элемента или компонента 1.5, убедитесь, что передан правильный тип. При использовании @
в связывании передаваемая переменная будет строкой, и если параметры, например,. целые числа, тогда появится пустая опция.
Либо правильно проанализируйте значение в init, либо связывание с <
и не @
(менее рекомендуется для работы без необходимости).
Обратитесь к примеру из документации angularjs, как преодолеть эти проблемы.
- Перейдите по этой ссылке документации здесь
- Найти 'Binding select к нестроковому значению с помощью синтаксического анализа / форматирования ngModel'
- Там вы можете видеть, что директива с именемconvertToNumber решает проблему.
Меня устраивает. Также можете посмотреть, как это работает здесь