为什么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>

我需要做什么才能摆脱它?

附注:没有这个也可以工作,但是如果使用select2而没有多重选择,它看起来很奇怪。

437290 次浏览

ng-model引用的值在传递给ng-options的一组选项中不存在时,会生成空的option。这是为了防止意外的模型选择:AngularJS可以看到初始模型是未定义的,或者不在选项集中,并且不想自己决定模型值。

如果你想去掉空选项,只需要在你的控制器中选择一个初始值,比如:

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

下面是jsFiddle: http://jsfiddle.net/MTfRD/3/

简而言之:空选项意味着没有选择有效的模型(有效的意思是:从选项集中)。您需要选择一个有效的模型值来去除这个空选项。

如果需要初始值,请参阅@pkozlowski。开源的答案,供你参考,它也可以在视图中(而不是在控制器中)使用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或“未选中”选项:

<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>
< p >
我也遇到过同样的问题。如果你要用普通的post来发布angular表单,那么你就会面临这个问题,因为angular不允许你像以前那样为选项设置值。如果你得到form的值。输入“然后你会找到正确的值。你必须将angular对象本身post而不是form post.

也许对某人有用:

如果你想使用普通选项而不是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清除空选项

虽然都是@pkozlowski。opensource和@Mark的答案是正确的,我想分享一下我稍微修改过的版本,我总是选择列表中的第一项,不管它的值是多少:

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

角& lt;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选择器,将目标内的第一个选项上面选择目标“真实”选项,而不是一个隐藏的。当您使用量角器进行端到端测试时,以及(无论出于何种原因)使用by.css()来瞄准选择选项时,它非常有用。

Angular >= 1.4

由于对select和options指令进行了重构,使用ng-if不再是一个可行的选项,因此您必须转向ng-show="false"以使其再次工作。

在你的控制器中试试这个,按相同的顺序:

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

当ng-model属性未定义时,ng-model将创建空选项值。如果我们将object赋值给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-model,不使用对象属性。如果你从服务器获取选择选项值,使用回调函数,将对象分配给ng-model

来自Angular文档的说明

注意:ngModel比较的是引用,而不是值。当绑定到对象数组时,这很重要。参见示例http://jsfiddle.net/qWzTb/

我试了很多次终于找到了。

下面是解决方案:

对于如下示例数据:

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,我可以在控制器中动态地做我的操作。

一个简单的解决方案是设置一个空值""的选项,我发现这消除了额外的未定义选项。

一个快速的解决方案:

select option:empty { display:none }

希望它能帮助到别人。理想情况下,选择的答案应该是方法,但如果这是不可能的,那么应该作为补丁工作。

这对我很有效

<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,但一旦选择它将消失,它不会显示在下拉列表中。

类似的事情也发生在我身上,这是由升级到angular 1.5引起的。在Angular的新版本中,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>

角& lt;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>

在这里的众多答案中,我认为我应该转发对我有效的解决方案,并满足以下条件中的所有:

  • 当ng-model是falsy时,提供一个占位符/提示。——select region——" w. value="")
  • 当ng-model值为falsy并且用户打开选项下拉菜单时,占位符被选中(这里提到的其他解决方案使第一个选项显示为选中,这可能会产生误导)
  • 允许用户取消选择一个有效值,实际上是再次选择falsy/默认值

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

原始的;原始的

好吧,实际上答案很简单:当有一个选项不能被Angular识别时,它就会包含一个无聊的选项。 你做错的是,当你使用ng-options时,它读取一个对象,说[{ id: 10, name: test }, { id: 11, name: test2 }] right?

这是你的模型值需要评估为相等,比如你想要选择的值为10,你需要设置你的模型的值为{ id: 10, name: test }以选择10,因此它不会创建垃圾。

希望这能帮助大家理解,我有一段艰难的时间尝试:)

我想补充一点,如果初始值来自某个父元素或1.5组件的绑定,请确保传递了正确的类型。如果在绑定中使用@,传递的变量将是string,如果选项为eg。整数,则会显示空选项。

要么正确解析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>

当你无法控制选项时,使用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();
}

我使用的是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>

如果你使用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>

现在它的工作,但在我的情况下,这是由于我删除范围从ng。控制器,检查你是否没有做同样的事情。

唯一对我有用的是在ng-options中使用track by,就像这样:

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

参考angularjs文档中的例子如何克服这些问题。

  1. 转到这个文档链接在这里
  2. 找到“# EYZ0”
  3. 你可以看到,指令“convertToNumber”解决了这个问题。

这对我很管用。还可以看到它是如何工作的在这里

我们可以使用CSS隐藏第一个选项,但它不会工作在IE 10, 11。最好的方法是使用Jquery删除该元素。此解决方案适用于chrome和IE10,11测试的主要浏览器

如果你使用的是angular,有时候使用setTimeout也可以

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