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

Sud*_*shu 644 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');
Run Code Online (Sandbox Code Playgroud)

在这里控制器:

$scope.typeOptions = [
    { name: 'Feature', value: 'feature' },
    { name: 'Bug', value: 'bug' },
    { name: 'Enhancement', value: 'enhancement' }
];
Run Code Online (Sandbox Code Playgroud)

最后,这是生成的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>
Run Code Online (Sandbox Code Playgroud)

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

PS:事情也没有这个,但如果你使用select2而没有多重选择,它看起来很奇怪.

pko*_*rce 639

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

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

$scope.form.type = $scope.typeOptions[0].value;
Run Code Online (Sandbox Code Playgroud)

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

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

  • 如果您使用数组并且`null`是您的值之一,那么遗憾的是这不起作用. (11认同)
  • 我试过两个$ scope.form.type =''; 和$ scope.form.type = $ scope.typeOptions [0],但我还是这个 - <option value ="?" 选择= "选择"> </选项> (7认同)
  • 是否可以在空的`<option>`中添加一个文本,这样就可以生成像`<option value ="?">选择一个选项</ option>` (6认同)
  • 有时在JS中使用这些数据真的没有意义.如果是服务器决定该选择中的内容,为什么JS必须复制它? (5认同)
  • @Tareck117只是wirte` <option value ="">选择一个选项</ option>`,它是选项列表的null-value.不需要?字符. (3认同)
  • 抱歉,带有HTML的行很长,以至于我没有注意到你是绑定名称,而不是完整的对象.请尝试使用$ scope.typeOptions [0] .value,如果这仍然不起作用,我将发送一个带有示例的jsFiddle. (2认同)
  • @ pkozlowski.opensource如果列表中没有任何内容怎么办?我不应该选择任何东西.在这种情况下做什么是正确的? (2认同)

Mar*_*cok 231

如果你想要一个初始值,请参阅@ 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>
Run Code Online (Sandbox Code Playgroud)

如果您不想要初始值,"单个硬编码元素(值设置为空字符串)可以嵌套到元素中.此元素将表示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>
Run Code Online (Sandbox Code Playgroud)

  • @hugo,工作小提琴:http://jsfiddle.net/4qKyx/1/注意显示"选择一个类型",但没有与之关联的值.一旦你选择了别的东西,你就不会再看到它了.(在Chrome上测试.) (4认同)
  • 在IE10中不起作用,"选择类型"始终可见且可选. (3认同)
  • 问题是您仍然可以使用键盘选择,请参阅http://stackoverflow.com/a/8442831/57344解决方案 (2认同)
  • 这可能现在可以使用,但角度文档特别建议不要使用ng-init进行除ng-repeat之外的任何操作 - 请参阅https://docs.angularjs.org/api/ng/directive/ngInit (2认同)

WTK*_*WTK 121

角度<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>
Run Code Online (Sandbox Code Playgroud)

为什么ng-if和not ng-hide?因为你想要css选择器将目标定位在上面的第一个选项,选择目标"真实"选项,而不是隐藏的选项.当您使用量角器进行e2e测试时(无论出于何种原因)使用by.css()来定位选择选项,它会变得非常有用.

角度> = 1.4

由于select和options指令的重构,使用ng-if不再是一个可行的选项,所以你必须转向ng-show="false"使它再次工作.

  • 应该是接受的答案,因为这是选择的正确视觉行为.你把`size ="5"`添加到选择属性,你可以看到没有选择任何东西!就像默认的`<select>`-Element一样!我无法理解为什么角度为没有'multiple`属性的选择做这样的事情... (5认同)
  • @Sander_P根据定义,这个解决方案在我看来是"hacky"编码(在dom中加入一些东西以欺骗角色将其取出),但你说得对,它仍然是"最好的"解决方案."更好"的解决方案是允许没有价值的friggin选择!有没有搞错?它不是一个边缘情况. (2认同)

Abr*_*esh 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>
Run Code Online (Sandbox Code Playgroud)

将模型设置为内联.使用ng-init摆脱空选项


Nab*_*oag 22

类似的东西也发生在我身上,是由于升级到1.5角.ng-init似乎是在较新版本的Angular中进行类型解析.在较旧的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>
Run Code Online (Sandbox Code Playgroud)

角度<1.2.x

<select ng-model="myModelName" ng-init="myModelName=600">
  <option value="600">First</option>
  <option value="700">Second</option>
</select>
Run Code Online (Sandbox Code Playgroud)

角度> 1.2

<select ng-model="myModelName" ng-init="myModelName='600'">
  <option value="600">First</option>
  <option value="700">Second</option>
</select>
Run Code Online (Sandbox Code Playgroud)

  • 当然可以,但是更好的选择是在“选项”中使用“ ng-value =“ 600””而不是“ value”。它将解析为一个数字,而您不必像现在这样转换值:) (3认同)
  • 谢谢!就我而言,我无法使用 ng-init (无默认值),因此我将模型转换为字符串并且它起作用了! (2认同)

jus*_*opi 20

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

  • 当ng模型是假的时候提供占位符/提示(例如"--select region--"w.)value=""
  • 当ng-model值为,用户打开选项下拉列表时,会选择占位符(此处提到的其他解决方案会使第一个选项显示为选中,这可能会产生误导)
  • 允许用户取消选择有效值,实质上再次选择falsy/default值

在此输入图像描述

<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>
Run Code Online (Sandbox Code Playgroud)

SRC

原始q&a - /sf/answers/2301665901/


K K*_*K K 16

快速解决方案:

select option:empty { display:none }
Run Code Online (Sandbox Code Playgroud)

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

  • 根据我的测试,这只适用于Chrome(新Chrome,最重要的是)和Firefox.IE和Safari休息.不了解歌剧和其他边缘浏览器.无论哪种方式,遗憾的是,这不是一个很好的解决方案. (2认同)

Kan*_*vel 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>
Run Code Online (Sandbox Code Playgroud)

重要的提示:

将$ scope.collections [0]或$ scope.collections [1]等数组的对象分配给ng-model,不要使用对象属性.如果从服务器获取选择值,使用回调函数,将对象分配给ng-model

来自Angular文档的注释

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

我已经尝试了很多次,终于找到了它.


小智 8

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

<select ng-options="option.value as option.name for option in typeOptions" ng-init="form.type=typeOptions[0].value">
</select>
Run Code Online (Sandbox Code Playgroud)