为什么AngularJS在select中包含一个空选项?

时间:2012-09-29 17:04:45

标签: 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而没有多重选择,它看起来很奇怪。

26 个答案:

答案 0 :(得分:633)

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

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

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

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

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

答案 1 :(得分:225)

如果你想要一个初始值,请参阅@ pkozlowski.opensource的答案,其中也可以使用ng-init在视图中(而不是在控制器中)实现FYI:

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

答案 2 :(得分:118)

Angular&lt; 1.4

对于那些对待&#34; null&#34;作为其中一个选项的有效值(所以想象&#34; null&#34;是下面示例中 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选择器以上面的第一个选项为目标,选择目标&#34;真实&#34;选项,而不是隐藏的选项。当您使用量角器进行e2e测试时(以及出于何种原因)使用by.css()来定位选择选项时,它会非常有用。

Angular&gt; = 1.4

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

答案 3 :(得分: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摆脱空选项

答案 4 :(得分:21)

类似的东西也发生在我身上,是由于角色1.5的升级造成的。ng-init似乎在较新版本的Angular中为 type 进行了解析。在较旧的Angular ng-init="myModelName=600"中,将映射到值为&#34; 600&#34;的选项。即<option value="600">First</option>,但在Angular 1.5中,它不会发现这一点,因为它似乎期望找到值为600的选项,即<option value=600>First</option>。然后Angular将随机插入第一项:

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

Angular&lt; 1.2.x的

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

Angular&gt; 1.2

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

答案 5 :(得分:20)

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

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

原始q&amp; a - https://stackoverflow.com/a/32880941/1121919

答案 6 :(得分:15)

快速解决方案:

select option:empty { display:none }

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

答案 7 :(得分:13)

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

我终于尝试了很多次。

答案 8 :(得分:8)

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

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

答案 9 :(得分:3)


我遇到了同样的问题。如果您使用普通帖子发布角度表单,那么您将面临此问题,因为角度不允许您以您使用的方式设置选项的值。如果您获得“form.type”的值,那么您将找到正确的值。你必须自己发布角度对象而不是表格帖子。

答案 10 :(得分:3)

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

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

希望它能帮助每个人理解,我有一段艰难的时间尝试:)

答案 11 :(得分:3)

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

答案 12 :(得分:2)

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

答案 13 :(得分: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>

答案 14 :(得分: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,但一旦选择它将消失,并且它不会显示在下拉列表中。

答案 15 :(得分:0)

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

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

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

答案 16 :(得分:0)

请参阅angularjs文档中的示例,以解决这些问题。

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

对我有用。还可以查看其工作原理here

答案 17 :(得分: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">

答案 18 :(得分:0)

您好我有一些jquery移动参考,我删除了它们。使用jQuery mobile,上述任何修复都不适用于我。 (如果有人可以解释jQuery Mobile和Angular JS之间的冲突,那就很棒了)

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

答案 19 :(得分:0)

我有同样的问题, 我(删除&#34; ng-model&#34;)改变了这个:

<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删除了该范围,检查你是否也没有这样做。

答案 20 :(得分:0)

如果您使用ng-init模型来解决此问题:

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

答案 21 :(得分:0)

当您无法控制选项

时,使用jQuery进行研磨解决方案

HTML:

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

JS:

#building dataframe with variables
bframe <- data.frame(matrix(ncol = 3, nrow = 10000))
x <- c("curpage", "nexturl", "posttext")
colnames(bframe) <- x

#assigning first value for nexturl
bframe$nexturl[[1]] <- "http://www.ashleyannphotography.com/blog/2017/04/02/canopy-anna-turner/"

答案 22 :(得分: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>

答案 23 :(得分:0)

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

要么正确解析init中的值,要么绑定<而不是@(除非必要,否则建议不要提高性能)。

答案 24 :(得分: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,我可以动态地在控制器中进行操作。

答案 25 :(得分:0)

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

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