AngularJS-选择的value属性


72

源JSON数据为:

[
  {"name":"Alabama","code":"AL"},
  {"name":"Alaska","code":"AK"},
  {"name":"American Samoa","code":"AS"},
  ...
]

我尝试

ng-options="i.code as i.name for i in regions"

但正在得到:

<option value="?" selected="selected"></option>
<option value="0">Alabama</option>
<option value="1">Alaska</option>
<option value="2">American Samoa</option>

当我期望得到:

<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AS">American Samoa</option>

那么,如何获取价值属性并摆脱“?”?项目?

顺便说一句,如果我将$ scope.regions设置为静态JSON而不是AJAX请求的结果,则空项消失。



2
使用-region in regions track by region.code将value属性设置为region.code value;)
taystack 2015年

Answers:


75

您最初尝试过的方法应该可以使用,但是HTML不是我们所期望的。我添加了一个选项来处理最初的“未选择项目”情况:

<select ng-options="region.code as region.name for region in regions" ng-model="region">
   <option style="display:none" value="">select a region</option>
</select>
<br>selected: {{region}}

上面产生了这个HTML:

<select ng-options="..." ng-model="region" class="...">
   <option style="display:none" value class>select a region</option>
   <option value="0">Alabama</option>
   <option value="1">Alaska</option>
   <option value="2">American Samoa</option>
</select>

小提琴

即使Angular使用数字整数作为值,该模型(即$ scope.region)也将根据需要设置为AL,AK或AS。(当从列表中选择一个选项时,Angular会使用该数值查找正确的数组条目。)

第一次学习Angular如何实现其“ select”指令时,这可能会造成混淆。


14
我感到困惑,并且缺乏透明度,因为HTML无法反映范围内设置的值...
Dofs

3
这是另一种思维方式。您实际上是在选择region 对象,而不是region.code 字符串。一旦用户选择了某项,就将选择该region 对象。然后,当您以后需要代码时,只需访问region.code。希望能有所帮助。
杰西

3
有人可以解释一下“ region.code as region.name”的语法实际上是在“说”吗……对我而言,这似乎毫无意义。该“ as”关键字完全使我失望,因为我认为它在语法上没有任何意义。
ProxyTech

4
@ProxyTech,我是这样想的:使用region.code作为分配给模型的值,但向用户显示region.name。该API文档指region.name一部分的label
Mark Rajcok

3
@MarkRajcok这是我的C#范例,导致与用于将类型从类型转换为另一个的“ as”关键字引起混淆。然后是我的“英语”范例,关键字“ as”表示“ region.came”正在交互/替代“ region.code”……在上下文中完全不是这种情况。我认为语法很差。
ProxyTech 2014年

26

除非您自己在ng-repeat中构建它们,否则您无法真正做到这一点。

<select ng-model="foo">
   <option ng-repeat="item in items" value="{{item.code}}">{{item.name}}</option>
</select>

但是...可能不值得。最好保留它的设计功能,并让Angular处理内部工作。Angular以这种方式使用索引,因此您实际上可以将整个对象用作值。因此,您可以使用下拉绑定来选择整个值,而不仅仅是字符串,这非常棒:

<select ng-model="foo" ng-options="item as item.name for item in items"></select>

{{foo | json}}

3
尽管您的第一个示例生成了一个工作列表/正确的选择列表,并且提醒您不要使用它,但请注意,它与Angular的其余部分效果不佳。例如,这将无法正常工作:<a ng-click="foo ='AK'">选择AK </a>。通常,value属性可能不应与Angular select指令一起使用。
Mark Rajcok

这是关于围绕一个长期运行的bug一个很好的方式track by,并select没有一起工作。有关错误报告,请参见此处: github.com/angular/angular.js/issues/6564
Jack M.

22

如果使用该track by选项,value则正确编写属性,例如:

<div ng-init="a = [{label: 'one', value: 15}, {label: 'two', value: 20}]">
    <select ng-model="foo" ng-options="x for x in a track by x.value"/>
</div>

产生:

<select>
    <option value="" selected="selected"></option>
    <option value="15">one</option>
    <option value="20">two</option>
</select>

1
这在Angular 1.3 kittyminky中非常有效,也许检查一下语法。-这应该是选定的答案。
taystack

7

如果为下拉列表指定的模型不存在,则angular将生成一个空的options元素。因此,您将必须在select上明确指定模型,如下所示:

<select ng-model="regions[index]" ng-options="....">

请参考以下内容,因为之前已经回答过:

为什么AngularJS在select中包含一个空选项?和这个小提琴

更新:尝试以下操作:

<select ng-model="regions[index].code" ng-options="i.code as i.name for i in regions">
</select>

or

<select ng-model="regions[2]" ng-options="r.name for r in regions">
</select>

请注意,select中没有空的options元素。


5

您可以将模型修改为如下所示:

$scope.options = {
    "AL" : "Alabama",
    "AK" : "Alaska",
    "AS" : "American Samoa"
  };

然后使用

<select ng-options="k as v for (k,v) in options"></select>

此变体不起作用。它会生成具有相同数值和文本的选项,或者具有数值和空文本的选项,具体取决于顺序:“ k等于v”还是“ v等于k”
Paul

4

似乎不可能以任何有意义的方式实际使用select的“值”作为普通的HTML表单元素,并且也不能通过ng-options以批准的方式将其连接到Angular。作为一种折衷,我最终不得不在我的选择旁边放置一个隐藏的输入,并使它跟踪与我的选择相同的模型,如下所示(为简洁起见,所有这些都从真实的生产代码中大大简化了):

HTML:

<select ng-model="profile" ng-options="o.id as o.name for o in profiles" name="something_i_dont_care_about">
</select>
<input name="profile_id" type="text" style="margin-left:-10000px;" ng-model="profile"/>

Javascript:

App.controller('ConnectCtrl',function ConnectCtrl($scope) {
$scope.profiles = [{id:'xyz', name:'a profile'},{id:'abc', name:'another profile'}];
$scope.profile = -1;
}

然后,在我的服务器端代码中,我只是寻找 params[:profile_id](这碰巧是一个Rails应用程序,但是相同的原理在任何地方都适用)。由于隐藏的输入与选择的模型跟踪相同的模型,因此它们会自动保持同步(无需其他JavaScript)。这是Angular最酷的部分。它几乎弥补了它对value属性所做的副作用。

有趣的是,我发现该技术仅适用于未隐藏的输入标签(这就是为什么我不得不使用margin-left:-10000px;技巧将输入移出页面的原因)。这两个变体不起作用:

<input name="profile_id" type="text" style="display:none;" ng-model="profile"/>

<input name="profile_id" type="hidden" ng-model="profile"/>

我觉得那一定意味着我错过了一些东西。对于Angular来说,这似乎太不可思议了。


您也可以使用<input name="profile_id" type="hidden" value="{{profile}}"/>。有用。
harrrrrrry,2015年

1

您可以使用

state.name for state in states track by state.code

在JSON数组中的状态中,状态是数组中每个对象的变量名。

希望这可以帮助


-2

尝试如下:

var scope = $(this).scope();
alert(JSON.stringify(scope.model.options[$('#selOptions').val()].value));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.