如何在AngularJS的ng-options中设置value属性?

这似乎是困扰了很多人(包括我)。

当在AngularJS中使用ng-options指令来填充<select>标签的选项时,我不知道如何设置选项的值。 这方面的文档还不太清楚 – 至少对于像我这样的傻瓜来说。

我可以很容易地设置一个选项的文本,如下所示:

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

resultOptions是例如:

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

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

选择

ngOptions(可选) – { comprehension_expression= } – 采用以下形式之一:

对于数组数据源对于数组 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 对数据进行 select as label group by group for value in array track by trackexpr 对于对象数据源: 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元素的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>元素中显示的文本(标签)。

就像我们在代码中需要person.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)对解构。

价值属性如何得到它的价值:

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

所以你的情况应该是:

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

我也有这个问题。 我无法在ng选项中设定我的价值。 每个生成的选项都设置为0,1,…,n。

为了做到这一点,我在我的ng选项中做了这样的事情:

HTML:

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

我使用“跟踪”来设置所有我的价值与room.price

(这个例子很糟糕,因为如果有不止一个价格相等的话,代码就会失败,所以请确保有不同的值。)

JSON:

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

我从博客文章中了解到如何使用Angular.JS ng-options&track by来设置select元素的初始选定值

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

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

 <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 }}" /> 

预期值将通过表格以正确的名字发送。

使用常规表单将名为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}}" /> 

服务器将接收ironsuper作为my_hero的值。

这与@neemzy的答案类似,但为value属性指定单独的数据。

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

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

  • 如何向用户呈现查询行是(V)的关注点,并且ng-options提供了for关键字来指示选项元素的内容应该是什么, 即, p.text for p in resultOptions
  • (M)odel的担心是如何将一个选定的行提供给服务器。 因此, ng-options提供了as关键字来指定为模型提供的值,如k as v for (k,v) in objects

正确的解决方案是问题,然后是架构性的,涉及重构您的HTML,以便(M)odel在需要时 (而不是用户提交表单) 执行服务器通信

如果一个MVC HTML页面对于手头的问题是不必要的过度工程:那么只使用AngularJS(V)组件的HTML生成部分。 在这种情况下,请按照&lt;li /&gt;&lt;ul /&gt; 并且在选项元素上放置一个ng-repeat:

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

作为kludge ,总是可以将select元素的name属性移动到隐藏的input元素中:

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

你可以这样做:

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

今天我一直在努力解决这个问题。 我阅读了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 。 使用所选项目的track by将总是返回与固件ID相匹配的对象,而不是固件ID本身。 现在这符合我的标准,它应该返回一个数值而不是对象,并且使用ng-options来获得它所提供的性能改进,而不是为每个生成的选项创建一个新的范围。

另外,我需要空白的第一行,所以我只是给<select>元素添加一个<option>

这是一个显示我的工作的普朗克 。

如果您希望值与文本相同,您可以简单地使用数组来完成此操作,而不是使用新的“追踪”功能。

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

因为v变成v v

我发现这只是基于常识来看待语法。 (k,v)是将数组/对象拆分为键值对的实际语句。

在“k as v”语句中,k是值,v是显示给用户的文本选项。 我认为“跟踪”是混乱和矫枉过正。

根据我的说法,这是最适合所有情况的:

 <select ng-model="mySelection.value"> <option ng-repeat="r in myList" value="{{r.Id}}" ng-selected="mySelection.value == r.Id">{{r.Name}} </option> </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'}

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

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

使用limit.value as limit.text for limit in limits意味着:

<option>的标签设置为limit.text
limit.value值保存到select的ng-model

请参阅堆栈溢出问题AngularJS ng-选项不呈现值

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

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

不过,我只是想强调,“select”在这个上下文中不是关键字,但它只是一个表达式的占位符。 有关“select”表达式的定义以及在ng-options指令中可以使用的其他表达式,请参阅以下列表。

在问题中描述的select的使用:

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

本质上是错误的。

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


从AngularJS的ng选项文档:

  • 数组/对象 :一个表达式,计算一个数组/对象来迭代。
  • value :在迭代过程中引用数组中每个项的局部变量或者对象的每个属性值。
  • key :在迭代期间将引用对象中的属性名称的局部变量。
  • label :这个表达式的结果将是元素的标签。 表达式很可能会引用值变量(例如value.propertyName)。
  • 选择 :这个表达式的结果将被绑定到父元素的模型。 如果未指定,则选择表达式将默认为值。
  • group :这个表达式的结果将被用于使用DOM元素对选项进行分组。
  • trackexpr :使用对象数组时使用。 这个表达式的结果将被用来识别数组中的对象。 trackexpr很可能会引用值变量(例如value.propertyName)。

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

经过一段时间的挣扎之后,我用最常用的数据源做了一个样本。 你可以在这里找到它:

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

现在让ng选项工作,这里有一些事情要考虑:

  1. 通常情况下,您从一个来源获得选项,从另一个来源获得选定的值。 例如:
    • states :: ng-options的数据
    • user.state ::选项设置为选中
  2. 基于1,最简单/合乎逻辑的做法是用一个源填充选择,然后通过代码设置选定的值。 很少会有更好的混合数据集。
  3. AngularJS允许选择控件保存多个key | label key | label 。 许多在线的例子都把对象当作“关键”,如果你需要从对象中获取信息,就用这种方式设置对象,否则使用你需要的特定属性作为关键。 (ID,CODE等。如在PLKR样本中)
  4. 设置下拉/选择控件的值的方法取决于#3,

    • 如果下拉键是一个单独的属性(就像在PLUNK中的所有例子),你只需要设置它,例如: $scope.dropdownmodel = $scope.user.state;
    • 如果将对象设置为键,则需要循环选项,即使分配对象也不会将该项设置为选定项,因为它们将具有不同的哈希键,例如:

       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的相同属性的$scope.myObject.myProperty

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

但实际上,您不必担心设置选项的值属性。 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 } }); 

正如你可以在小提琴输出中看到的,无论你选择哪个选择框选项,它都是你的自定义值,或者AngularJS的0,1,2自动生成的值,除非你使用jQuery或者任何其他的其他库访问该组合框选项的值,并相应地操作它。

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

你已经问过如何选择这个选项,但没有人说过这两件事情是一样的:

如果我们有这样的选项:

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

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

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

这将无法正常工作,但如果您尝试选择这样的选项:

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

它会工作

即使这两个对象具有相同的属性,AngularJS也将它们视为不同,因为AngularJS通过引用进行比较。

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

对于一个对象:

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

使用ng选项对开发者来说总是很痛苦。 例如:在选择标签中获取一个空的/空的选定值。 尤其是在处理ng选项中的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> 

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

另一个参考 :

教程ANGULAR.JS:NG-SELECT和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> 

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

请尝试

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

这将分配带有文本和值的标签(来自数组)

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

运行代码片段并查看变体。 这里有便于理解的注释

  1. 示例1(对象选择): – ng-option="os.name for os in osList track by os.id" 。 这里track by os.id是重要的, 应该在那里和os.id as之前不应该os.name

    • ng-model="my_os"应该设置为一个对象,其关键字为my_os={id: 2}
  2. 例2(值选择): – ng-option="os.id as os.name for os in osList" 。 这里track by os.id 应该在那里, os.id as 应该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> 

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

 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显示正确的选项值。

ngOptions指令:

 $scope.items = [{name: 'a', age: 20},{ name: 'b', age: 30},{ name: 'c', age: 40}]; 
  • 情况1)数组中的值标签:

     <div> <p>selected item is : {{selectedItem}}</p> <p> age of selected item is : {{selectedItem.age}} </p> <select ng-model="selectedItem" ng-options="item.name for item in items"> </select> </div> 

输出说明(假定第一个项目被选中):

selectedItem = {名称:'a',年龄:20} // [默认情况下,所选项目等于值项目 ]

selectedItem.age = 20

  • 情况-2)在数组中选择作为标签的值:

     <div> <p>selected item is : {{selectedItem}}</p> <select ng-model="selectedItem" ng-options="item.age as item.name for item in items"> </select> </div> 

输出解释(假设第一个项目被选中): selectedItem = 20 // [选择零件是item.age ]