以下是困扰很多人(包括我)的问题。

当在AngularJS中使用ng-options指令来填充<select>标记的选项时,我不知道如何为一个选项设置值。这方面的文档确实不清楚——至少对我这样的傻瓜来说是这样。

我可以像这样轻松地设置一个选项的文本:

ng-options="select p.text for p in resultOptions"

例如,当resultOptions为:

[
    {
        "value": 1,
        "text": "1st"
    },
    {
        "value": 2,
        "text": "2nd"
    }
]

它应该是(可能是)设置选项值最简单的事情,但到目前为止,我只是不明白它。


See ngOptions ngOptions(optional) – {comprehension_expression=} – in one of the following forms: For array data sources: label for value in array select as label for value in array label group by group for value in array select as label group by group for value in array track by trackexpr For object data sources: label for (key , value) in object select as label for (key , value) in object label group by group for (key, value) in object select as label group by group for (key, value) in object

对你来说,应该是

array = [{ "value": 1, "text": "1st" }, { "value": 2, "text": "2nd" }];

<select ng-options="obj.value as obj.text for obj in array"></select>

更新

随着AngularJS的更新,现在可以用track by表达式为select element的value属性设置实际值了。

<select ng-options="obj.text for obj in array track by obj.value">
</select>

如何记住这些丑陋的东西

对于那些很难记住这种语法形式的人:我同意这不是最简单或最漂亮的语法。这种语法是Python列表推导式的扩展版本,知道这一点有助于我很容易地记住语法。大概是这样的:

Python代码:

my_list = [x**2 for x in [1, 2, 3, 4, 5]]
> [1, 4, 9, 16, 25]

# Let people to be a list of person instances
my_list2 = [person.name for person in people]
> my_list2 = ['Alice', 'Bob']

这实际上与上面列出的第一个语法相同。但是,在<select>中,我们通常需要区分代码中的实际值和<select>元素中显示的文本(标签)。

比如,我们需要人手。Id,但我们不想把Id显示给用户;我们想要显示它的名字。同样,我们对代码中的person.name不感兴趣。这里有as关键字来标记东西。所以它变成了这样:

person.id as person.name for person in people

或者,代替person。Id我们可能需要person实例/引用本身。见下文:

person as person.name for person in people

对于JavaScript对象,同样的方法也适用。只需要记住,对象中的项是用(key, value)对解构的。


value属性如何获取其值:

当使用数组作为数据源时,它将是数组元素在每次迭代中的索引; 当使用对象作为数据源时,它将是每次迭代中的属性名。

所以在你的例子中,它应该是:

obj = { '1': '1st', '2': '2nd' };

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

你可以这样做:

<select ng-model="model">
    <option value="">Select</option>
    <option ng-repeat="obj in array" value="{{obj.id}}">{{obj.name}}</option>
</select>

- - -更新

经过一些更新后,用户frm。Adiputra的解决方案要好得多。代码:

obj = { '1': '1st', '2': '2nd' };
<select ng-options="k as v for (k,v) in obj"></select>

如果你想改变选项元素的值,因为表单最终会提交给服务器,而不是这样做,

<select name="text" ng-model="text" ng-options="select p.text for p in resultOptions"></select>

你可以这样做:

<select ng-model="text" ng-options="select p.text for p in resultOptions"></select>
<input type="hidden" name="text" value="{{ text }}" />

然后,期望的值将以正确的名称通过表单发送。


ng-options指令不会为数组的<options>元素设置value属性:

使用限制。值为极限。“limits”中的“limit”表示:

将<option>的标签设置为limit.text 保存限制。Value值到选择的ng-model中

参见Stack Overflow问题AngularJS ng-options不呈现值。


对于对象:

<select ng-model="mySelect" ng-options="key as value for (key, value) in object"></select>

这个问题的正确答案由用户frm提供。Adiputra,因为目前这似乎是显式控制选项元素的value属性的唯一方法。

然而,我只是想强调,“select”在这里不是关键字,而只是表达式的占位符。请参考以下列表,“select”表达式的定义以及ng-options指令中可以使用的其他表达式。

问题中描述的select的用法:

ng-options='select p.text for p  in resultOptions'

本质上是错误的。

根据表达式列表,当在对象数组中给出选项时,似乎可以使用trackexpr来指定值,但它仅用于分组。


来自AngularJS的ng-options文档:

array / object: an expression which evaluates to an array / object to iterate over. value: local variable which will refer to each item in the array or each property value of object during iteration. key: local variable which will refer to a property name in object during iteration. label: The result of this expression will be the label for element. The expression will most likely refer to the value variable (e.g. value.propertyName). select: The result of this expression will be bound to the model of the parent element. If not specified, select expression will default to value. group: The result of this expression will be used to group options using the DOM element. trackexpr: Used when working with an array of objects. The result of this expression will be used to identify the objects in the array. The trackexpr will most likely refer to the value variable (e.g. value.propertyName).


ng-options看起来使用起来很复杂(可能令人沮丧),但实际上我们有一个架构问题。

AngularJS是动态HTML+JavaScript应用程序的MVC框架。虽然它的(V)视图组件确实提供了HTML“模板”,但它的主要目的是通过控制器将用户操作连接到模型中的更改。因此,在AngularJS中,适当的抽象级别是select元素将模型中的值设置为来自查询的值。

查询行如何呈现给用户是(V)视图关心的问题,ng-options提供了for关键字来指示选项元素的内容应该是什么,即p.text for resultOptions中的p。 所选的行如何呈现给服务器是(M)模型所关心的。因此ng-options提供了as关键字来指定在对象中(k,v)的k和v中向模型提供什么值。

这个问题的正确解决方案是本质上的体系结构,并涉及重构HTML,以便(M)模型在需要时执行服务器通信(而不是用户提交表单)。

如果一个MVC HTML页面对于手头的问题来说是不必要的过度工程:那么只使用AngularJS的(V)视图组件的HTML生成部分。在这种情况下,遵循与生成&lt;ul /&gt;'s下的&lt;li /&gt;'s相同的模式,并在一个选项元素上放置ng-repeat:

<select name=“value”>
    <option ng-repeat=“value in Model.Values” value=“{{value.value}}”>
        {{value.text}}
    </option>
</select>

作为临时拼凑,我们总是可以将选择元素的name属性移动到一个隐藏的输入元素:

<select ng-model=“selectedValue” ng-options=“value.text for value in Model.Values”>
</select>
<input type=“hidden” name=“value” value=“{{selectedValue}}” />

用一个普通的表单提交发送一个名为my_hero的自定义值给服务器:

JSON:

"heroes": [
  {"id":"iron", "label":"Iron Man Rocks!"},
  {"id":"super", "label":"Superman Rocks!"}
]

HTML:

<select ng-model="hero" ng-options="obj.id as obj.label for obj in heroes"></select>
<input type="hidden" name="my_hero" value="{{hero}}" />

服务器将接收my_hero的值为iron或super。

这类似于@neemzy的回答,但是为value属性指定了单独的数据。


<select ng-model="color" ng-options="(c.name+' '+c.shade) for c in colors"></select><br>

在ng-options中选择一个项目可能有点棘手,这取决于您如何设置数据源。

在与它们斗争了一段时间后,我最终用我使用的最常用的数据源制作了一个样本。你可以在这里找到它:

http://plnkr.co/edit/fGq2PM?p=preview

现在要让ng-options工作,需要考虑以下几点:

Normally you get the options from one source and the selected value from other. For example: states :: data for ng-options user.state :: Option to set as selected Based on 1, the easiest/logical thing to do is to fill the select with one source and then set the selected value trough code. Rarely would it be better to get a mixed dataset. AngularJS allows select controls to hold more than key | label. Many online examples put objects as 'key', and if you need information from the object set it that way, otherwise use the specific property you need as key. (ID, CODE, etc.. As in the plckr sample) The way to set the value of the dropdown/select control depends on #3, If the dropdown key is a single property (like in all examples in the plunkr), you just set it, e.g.: $scope.dropdownmodel = $scope.user.state; If you set the object as key, you need to loop trough the options, even assigning the object will not set the item as selected as they will have different hashkeys, e.g.: for (var i = 0, len = $scope.options.length; i < len; i++) { if ($scope.options[i].id == savedValue) { // Your own property here: console.log('Found target! '); $scope.value = $scope.options[i]; break; } }

您可以在另一个对象$scope.myObject.myProperty中替换相同属性的savedValue。


一年后,我不得不找到这个问题的答案,因为这些问题都没有给出实际答案,至少对我来说是这样。

你问过如何选择选项,但没有人说这两件事不一样:

如果我们有这样的选项:

$scope.options = [
    { label: 'one', value: 1 },
    { label: 'two', value: 2 }
  ];

我们试着像这样设置一个默认选项:

$scope.incorrectlySelected = { label: 'two', value: 2 };

它不会工作,但如果你尝试选择这样的选项:

$scope.correctlySelected = $scope.options[1];

它会起作用的。

尽管这两个对象具有相同的属性,AngularJS仍然将它们视为DIFFERENT,因为AngularJS是通过引用进行比较的。

看看小提琴http://jsfiddle.net/qWzTb/。


我也有这个问题。我不能在ng-options中设置我的值。生成的每个选项都设置为0,1,…, n。

为了让它正确,我在ng-options中做了这样的事情:

HTML:

<select ng-options="room.name for room in Rooms track by room.price">
    <option value="">--Rooms--</option>
</select>

我使用“track by”来设置所有的room.price值。

(这个例子很糟糕:因为如果有多个价格相等,代码就会失败。所以一定要有不同的值。)

JSON:

$scope.Rooms = [
            { name: 'SALA01', price: 100 },
            { name: 'SALA02', price: 200 },
            { name: 'SALA03', price: 300 }
        ];

我从一篇博客文章中学会了如何使用Angular.JS ng-options & track by设置一个选择元素的初始选择值。

观看视频。这是一个很好的类:)


开发人员使用ng-options总是很痛苦的。例如:在select标记中获取空/空的选定值。特别是在ng-options中处理JSON对象时,它变得更加乏味。这里我已经做了一些练习。

目的:通过ng-option迭代JSON对象数组,并设置选中的第一个元素。

数据:

someNames = [{"id":"1", "someName":"xyz"}, {"id":"2", "someName":"abc"}]

在选择标签中,我必须显示xyz和abc,其中xyz必须毫不费力地选择。

HTML:

<pre class="default prettyprint prettyprinted" style=""><code>
    &lt;select class="form-control" name="test" style="width:160px"    ng-options="name.someName for name in someNames" ng-model="testModel.test" ng-selected = "testModel.test = testModel.test || someNames[0]"&gt;
&lt;/select&gt;
</code></pre>

通过上面的代码示例,您可能会摆脱这种夸张。

另一个参考:


而不是使用新的'track by'功能,你可以简单地对一个数组这样做,如果你想要的值与文本相同:

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

注意标准语法之间的区别,标准语法将使值成为对象/数组的键,因此对于数组来说是0、1、2等:

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

K (v)变成了v (v)

我是根据语法常识发现这一点的。 (k,v)是将数组/对象拆分为键值对的实际语句。

在'k as v'语句中,k将是值,v将是显示给用户的文本选项。我认为“track by”是一种混乱和过度的表达。


教程ANGULAR.JS: NG-SELECT AND NG-OPTIONS帮我解决了这个问题:

<select id="countryId"
  class="form-control"
  data-ng-model="entity.countryId"
  ng-options="value.dataValue as value.dataText group by value.group for value in countries"></select>

这就是我解决这个问题的方法。我根据值跟踪了选择,并在JavaScript代码中将所选项目属性设置为模型。

Countries =
[
    {
        CountryId = 1, Code = 'USA', CountryName = 'United States of America'
    },
    {
       CountryId = 2, Code = 'CAN', CountryName = 'Canada'
    }
]
<select ng-model="vm.Enterprise.AdminCountry" ng-options="country.CountryName for country in vm.Countries track by country.CountryId">

vm是我的控制器,从服务检索到的控制器中的国家是{CountryId =1, Code =' USA', CountryName='United States of America'}。

当我从选择下拉菜单中选择了另一个国家,并发布了“保存”页面时,我得到了正确的国家边界。


对我来说,布鲁诺·戈麦斯的答案是最好的答案。

但实际上,您不需要担心设置select options的value属性。AngularJS会处理这个。让我详细解释一下。

请考虑这把小提琴

angular.module('mySettings', []).controller('appSettingsCtrl', function ($scope) {

    $scope.timeFormatTemplates = [{
        label: "Seconds",
        value: 'ss'
    }, {
        label: "Minutes",
        value: 'mm'
    }, {
        label: "Hours",
        value: 'hh'
    }];


    $scope.inactivity_settings = {
        status: false,
        inactive_time: 60 * 5 * 3, // 15 min (default value), that is, 900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.activity_settings = {
        status: false,
        active_time: 60 * 5 * 3, // 15 min (default value), that is,  900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.changedTimeFormat = function (time_format) {
        'use strict';

        console.log('time changed');
        console.log(time_format);
        var newValue = time_format.value;

        // do your update settings stuffs
    }
});

正如你在fiddle输出中看到的,无论你为选择框选项选择了什么,它都是你的自定义值,或者AngularJS自动生成的0、1、2值,这在你的输出中并不重要,除非你使用jQuery或任何其他库来访问选择组合框选项的值并相应地操作它。


就像很多人之前说的,如果我有这样的数据:

countries : [
              {
                 "key": 1,
                 "name": "UAE"
             },
              {
                  "key": 2,
                  "name": "India"
              },
              {
                  "key": 3,
                  "name": "OMAN"
              }
         ]

我会这样使用它:

<select
    ng-model="selectedCountry"
    ng-options="obj.name for obj  in countries">
</select>

在你的控制器中,你需要设置一个初始值来消除第一个空项:

 $scope.selectedCountry = $scope.countries[0];

 // You need to watch changes to get selected value
 $scope.$watchCollection(function() {
   return $scope.selectedCountry
 }, function(newVal, oldVal) {
     if (newVal === oldVal) {
       console.log("nothing has changed " + $scope.selectedCountry)
     } 
     else {
       console.log('new value ' + $scope.selectedCountry)
     }
 }, true)

以下是我如何在遗留应用程序中解决这个问题:

在HTML中:

ng-options="kitType.name for kitType in vm.kitTypes track by kitType.id" ng-model="vm.itemTypeId"

在JavaScript中:

vm.kitTypes = [
    {"id": "1", "name": "Virtual"},
    {"id": "2", "name": "Physical"},
    {"id": "3", "name": "Hybrid"}
];

...

vm.itemTypeId = vm.kitTypes.filter(function(value, index, array){
    return value.id === (vm.itemTypeId || 1);
})[0];

我的HTML正确地显示了选项值。


<select ng-model="output">
   <option ng-repeat="(key,val) in dictionary" value="{{key}}">{{val}}</option>
</select>

今天我已经为这个问题纠结了一段时间。我通读了AngularJS的文档,这篇文章和其他一些文章,还有一些它们指向的博客。他们都帮助我理解了更细微的细节,但最终这似乎是一个令人困惑的话题。主要是因为ng-options的许多语法细微差别。

最后,对我来说,它归结为少即是多。

给定一个作用域,配置如下:

        //Data used to populate the dropdown list
        $scope.list = [
           {"FirmnessID":1,"Description":"Soft","Value":1},         
           {"FirmnessID":2,"Description":"Medium-Soft","Value":2},
           {"FirmnessID":3,"Description":"Medium","Value":3}, 
           {"FirmnessID":4,"Description":"Firm","Value":4},     
           {"FirmnessID":5,"Description":"Very Firm","Value":5}];

        //A record or row of data that is to be save to our data store.
        //FirmnessID is a foreign key to the list specified above.
        $scope.rec = {
           "id": 1,
           "FirmnessID": 2
        };

这就是我想要得到的结果:

        <select ng-model="rec.FirmnessID"
                ng-options="g.FirmnessID as g.Description for g in list">
            <option></option>
        </select>   

注意,我没有使用track by。使用所选项的跟踪将总是返回与FirmnessID匹配的对象,而不是FirmnessID本身。这现在满足了我的标准,即它应该返回一个数值而不是对象,并且使用ng-options来获得它所提供的性能改进,而不是为生成的每个选项创建一个新的作用域。

同样,我需要空白的第一行,所以我简单地在<select>元素中添加了一个<option>。

这是一个展示我作品的Plunkr。


根据我的说法,这是最适合所有场景的:

<select ng-model="mySelection.value">
   <option ng-repeat="r in myList" value="{{r.Id}}" ng-selected="mySelection.value == r.Id">{{r.Name}}
   </option>
</select>

您可以使用您的模型来绑定数据。您将获得对象将包含的值以及基于您的场景的默认选择。


运行代码片段并查看变化。为了快速理解,这里有一个注释

例1(对象选择):- ng-option="os.name for os in osList track by os.id"。这里由os跟踪。Id是重要的&应该在那里和os。id不应该出现在os.name之前。 ng-model="my_os"应该设置为一个key为id的对象,例如my_os={id: 2}。 例2(取值选择):- ng-option="os. "id作为osList中os的os.name”。这里由os跟踪。id不应该在那里,os。Id应该在os.name之前。 ng-model="my_os"应该设置为my_os= 2这样的值

其余代码片段将进行解释。

angular.module('app', []).controller('ctrl', function($scope, $timeout){ //************ EXAMPLE 1 ******************* $scope.osList =[ { id: 1, name :'iOS'}, { id: 2, name :'Android'}, { id: 3, name :'Windows'} ] $scope.my_os = {id: 2}; //************ EXAMPLE 2 ******************* $timeout(function(){ $scope.siteList = [ { id: 1, name: 'Google'}, { id: 2, name: 'Yahoo'}, { id: 3, name: 'Bing'} ]; }, 1000); $scope.my_site = 2; $timeout(function(){ $scope.my_site = 3; }, 2000); }) fieldset{ margin-bottom: 40px; } strong{ color:red; } <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.10/angular.min.js"></script> <div ng-app="app" ng-controller="ctrl"> <!--//************ EXAMPLE 1 *******************--> <fieldset> <legend>Example 1 (Set selection as <strong>object</strong>)</legend> <select ng-model="my_os" ng-options="os.name for os in osList track by os.id"> <option value="">--Select--</option> </select> {{my_os}} </fieldset> <!--//************ EXAMPLE 2 *******************--> <fieldset> <legend>Example 2 (Set selection as <strong>value</strong>. Simulate ajax)</legend> <select ng-model="my_site" ng-options="site.id as site.name for site in siteList"> <option value="">--Select--</option> </select> {{my_site}} </fieldset> </div>


请使用属性跟踪来区分选择框中的值和标签。

请尝试

<select ng-options="obj.text for obj in array track by obj.value"></select>

它将为文本分配标签,并为value(来自数组)分配值


ngOptions指令:

$scope.items = [{name: 'a', age: 20},{ name: 'b', age: 30},{ name: 'c', age: 40}];

Case-1)数组中值的标签: < div > <p>selected item is: {{selectedItem}}</p> . {{selectedItem} <p>年龄的选定项目是:{{selectedItem。年龄}}< / p > <select ng-model="selectedItem" ng-options="item.name for item in items"> < /选择> < / div >

输出说明(假设选择了第一项):

selectedItem = {name: 'a', age: 20} //[默认情况下,所选项目等于值item]

selectedItem.age = 20

Case-2)为数组中的值选择标签: < div > <p>selected item is: {{selectedItem}}</p> . {{selectedItem} <select ng-model="selectedItem" ng-options="item。年龄为项目"> "中项目的item.name < /选择> < / div >

输出说明(假设选择了第一项): selectedItem = 20 // [select part is item.age]


您可以使用ng-options实现选择标记绑定到值和显示成员

在使用此数据源时

countries : [
              {
                 "key": 1,
                 "name": "UAE"
             },
              {
                  "key": 2,
                  "name": "India"
              },
              {
                  "key": 3,
                  "name": "OMAN"
              }
         ]

可以使用下面的代码将选择标记绑定到值和名称

<select name="text" ng-model="name" ng-options="c.key as c.name for c in countries"></select>

效果很好