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 请求的结果,则空项目会消失。

4

8 回答 8

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 如何实现它的“选择”指令时,这可能会让人感到困惑。

于 2012-12-10T20:33:13.260 回答
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}}
于 2012-12-10T15:36:17.307 回答
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>
于 2014-07-30T14:25:59.937 回答
7

如果为下拉列表指定的模型不存在,则 Angular 将生成一个空选项元素。因此,您必须像这样在 select 上明确指定模型:

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

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

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

更新:试试这个:

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

请注意,选择中没有空选项元素。

于 2012-12-10T15:36:33.420 回答
5

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

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

然后使用

<select ng-options="k as v for (k,v) in options"></select>
于 2012-12-10T15:38:56.150 回答
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 来说,这似乎太奇怪了。

于 2013-08-29T05:02:13.430 回答
1

您可以使用

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

JSON数组中的states,state是数组中每个对象的变量名。

希望这可以帮助

于 2014-10-21T06:35:56.967 回答
-2

尝试如下:

var scope = $(this).scope();
alert(JSON.stringify(scope.model.options[$('#selOptions').val()].value));
于 2014-12-22T03:26:47.637 回答