663

过去几周我一直在使用 AngularJS,而真正困扰我的一件事是,即使在尝试了http://docs.angularjs.org/api/ng规范中定义的所有排列或配置之后.directive: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 而没有多重选择,它看起来很奇怪。

4

26 回答 26

655

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

如果您想摆脱空选项,只需在控制器中选择一个初始值,例如:

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

这是 jsFiddle:http: //jsfiddle.net/MTfRD/3/

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

于 2012-09-29T17:26:45.853 回答
241

如果您想要一个初始值,请参阅@pkozlowski.opensource 的答案,仅供参考,也可以使用 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>
于 2012-12-10T21:09:14.127 回答
122

角度 < 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() 来定位选择选项时,它会变得很有用。

角度 >= 1.4

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

于 2014-06-20T06:48:23.920 回答
36

也许对某人有用:

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

于 2013-08-28T13:32:54.903 回答
24

类似的事情也发生在我身上,是由升级到 angular 1.5 引起的。ng-init似乎正在为较新版本的 Angular 中的类型进行解析。在较旧的 Angularng-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>
于 2016-03-17T14:47:01.810 回答
22

在这里的众多答案中,我想我会重新发布对我有用并满足以下所有条件的解决方案:

  • 当 ng-model错误时提供占位符/提示(例如“--select region-- ” w. value=""
  • 当 ng-model 值为falsy并且用户打开选项下拉菜单时,将选择占位符(此处提到的其他解决方案使第一个选项显示为已选中,这可能会产生误导)
  • 允许用户取消选择一个有效值,本质上是再次选择虚假/默认值

在此处输入图像描述

代码

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

源代码

原始问答 - https://stackoverflow.com/a/32880941/1121919

于 2016-04-27T14:53:49.427 回答
17

快速解决方案:

select option:empty { display:none }

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

于 2015-02-27T19:41:50.453 回答
14

是的,当 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.collections[0] 或 $scope.collections[1] 之类的数组对象分配给 ng-model,不要使用对象属性。如果您从服务器获取选择选项值,使用回调函数,将对象分配给 ng-model

来自 Angular 文档的注意事项

注意:ngModel 通过引用而不是值进行比较。这在绑定到对象数组时很重要。看一个例子http://jsfiddle.net/qWzTb/

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

于 2014-07-16T16:47:47.880 回答
9

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

<select ng-options="option.value as option.name for option in typeOptions" ng-init="form.type=typeOptions[0].value">
</select>
于 2014-06-11T18:02:11.157 回答
4

我正在使用 Angular 1.4x 并找到了这个示例,因此我使用 ng-init 在选择中设置初始值:

<select ng-init="foo = foo || items[0]" ng-model="foo" ng-options="item as item.id for item in items"></select>
于 2017-05-18T18:14:29.740 回答
3


I faced the same issue. If you are posting an angular form with normal post then you will face this issue, as angular don't allow you to set values for the options in the way you have used. If you get the value of "form.type" then you will find the right value. You have to post the angular object it self not the form post.

于 2013-02-03T11:13:23.217 回答
3

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

于 2015-02-26T18:58:03.843 回答
3

好的,实际上答案很简单:当有一个 Angular 无法识别的选项时,它包括一个沉闷的选项。你做错的是,当你使用 ng-options 时,它会读取一个对象,比如[{ id: 10, name: test }, { id: 11, name: test2 }] right?

这是您的模型值需要将其评估为相等的值,例如您希望选择的值为 10,您需要将模型设置{ id: 10, name: test }为选择 10 之类的值,因此它不会创建该垃圾。

希望它可以帮助大家理解,我很难尝试:)

于 2016-09-19T20:32:00.460 回答
2

这个解决方案对我有用:

<select ng-model="mymodel">    
   <option ng-value="''" style="display:none;" selected>Country</option>
   <option value="US">USA</option>
</select>
于 2018-02-26T09:12:06.360 回答
1

这对我有用

<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>
于 2015-12-15T15:56:49.217 回答
1

这工作得很好

<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选择之前的信息,但一旦选择它就会消失,并且不会出现在下拉列表中。

于 2016-01-12T16:06:42.567 回答
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为时value.listName,它会自动填充文本,value.listName但所选选项的值是value.listCount虽然我显示的值是正常的 0,1,2 .. 等等!!!

就我而言,financeRef.financeLimit实际上是在抓取value.listCount,我可以在控制器中动态地进行操作。

于 2014-09-03T18:31:43.147 回答
0

按照相同的顺序在您的控制器中尝试这个:

$scope.typeOptions = [
    { name: 'Feature', value: 'feature' }, 
    { name: 'Bug', value: 'bug' }, 
    { name: 'Enhancement', value: 'enhancement' }
];
$scope.form.type = $scope.typeOptions[0];
于 2014-06-25T07:34:45.620 回答
0

简单的解决方案

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

于 2017-01-28T14:26:06.413 回答
0

我有同样的问题,我(删除“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.controller 中删除了该范围,检查你是否没有这样做。

于 2017-09-13T08:52:02.193 回答
0

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

要么正确解析 init 中的值,要么使用<和不绑定@(除非必要,否则不推荐用于性能)。

于 2016-12-20T16:49:51.003 回答
0

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

此外,如果您使用 angular ,有时使用 setTimeout 可以

$scope.RemoveFirstOptionElement = function (element) {
    setTimeout(function () {
        $(element.children()[0]).remove();
    }, 0);
};
于 2019-08-30T01:51:09.373 回答
0

请参阅 angularjs 文档中的示例如何克服这些问题。

  1. 在此处转到此文档链接
  2. 查找“通过 ngModel 解析/格式化将选择绑定到非字符串值
  3. 在那里你可以看到,名为“ convertToNumber ”的指令解决了这个问题。

这个对我有用。也可以在这里查看它是如何工作

于 2019-03-22T07:41:36.167 回答
0

当您无法控制选项时,使用 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();
}
于 2017-04-05T13:23:50.200 回答
0

如果你使用 ng-init 你的模型来解决这个问题:

<select ng-model="foo" ng-app ng-init="foo='2'">
于 2017-08-23T19:05:11.060 回答
0

唯一对我有用的是使用track byin ng-options,如下所示:

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

于 2017-11-19T19:30:51.817 回答