How do I set the value property in AngularJS' ng-options?
这就是困扰很多人(包括我)的事情。
在AngularJS中使用
我可以轻松设置选项的文本,如下所示:
1 | ng-options="select p.text for p in resultOptions" |
例如,当
1 2 3 4 5 6 7 8 9 10 | [ { "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
在你的情况下,应该是
1 2 3 | array = [{"value": 1,"text":"1st" }, {"value": 2,"text":"2nd" }]; <select ng-options="obj.value as obj.text for obj in array"></select> |
更新
随着AngularJS的更新,现在可以使用
1 2 | <select ng-options="obj.text for obj in array track by obj.value"> </select> |
如何记住这些丑陋的东西
To all the people who are having hard time to remember this syntax form: I agree this isn't the most easiest or beautiful syntax. 这种语法是python列表理解的一种扩展版本,知道它可以帮助我很容易地记住语法。就像这样:
Python代码:
1 2 3 4 5 6 | 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'] |
这实际上与上面列出的第一个语法相同。然而,在
比如,我们在代码中需要
1 | person.id as person.name for person in people |
或者,我们可能需要
1 | person as person.name for person in people |
对于javascript对象,同样的方法也适用。请记住,对象中的项是用
值属性如何获取其值:
- 当使用数组作为数据源时,它将是每次迭代中数组元素的索引;
- 当使用对象作为数据源时,它将是每个迭代中的属性名。
所以在你的例子中应该是:
1 2 3 | obj = { '1': '1st', '2': '2nd' }; <select ng-options="k as v for (k,v) in obj"></select> |
我也有这个问题。我无法在ng选项中设置我的值。生成的每个选项都设置为0、1、…、n。
为了使它正确,我在我的NG选项中做了类似的事情:
HTML:1 2 3 | <select ng-options="room.name for room in Rooms track by room.price"> <option value="">--Rooms--</option> </select> |
我用"track by"来设置我的所有值。
(这个例子很糟糕:因为如果有多个价格相等,代码就会失败。所以一定要有不同的值。)
杰森:1 2 3 4 5 | $scope.Rooms = [ { name: 'SALA01', price: 100 }, { name: 'SALA02', price: 200 }, { name: 'SALA03', price: 300 } ]; |
我在博客上学到了如何使用angular.js ng options&track by设置选定元素的初始选定值。
观看视频。这是一门不错的课。)
如果您希望更改
1 | <select name="text" ng-model="text" ng-options="select p.text for p in resultOptions"></select> |
您可以这样做:
1 2 | <select ng-model="text" ng-options="select p.text for p in resultOptions"></select> <input type="hidden" name="text" value="{{ text }}" /> |
然后,期望值将以正确的名称通过表单发送。
要使用普通表单将名为
杰森:
1 2 3 4 5 6 7 | "heroes": [ {"id":"iron","label":"Iron Man Rocks! <hr><P>似乎<wyn>ng-options</wyn>的使用很复杂(可能令人沮丧),但实际上我们有一个体系结构问题。</P><P>AngularJS是动态HTML+javascript应用程序的MVC框架。虽然它的(v)iew组件提供了HTML"模板化",但其主要目的是通过控制器将用户操作连接到模型中的更改。因此,在AngularJS中工作的适当抽象级别是,select元素将模型中的值设置为查询中的值。</P><ul><li>查询行如何呈现给用户是(v)视图的关注点,<wyn>ng-options</wyn>提供<wyn>for</wyn>关键字来指定选项元素的内容,即<wyn>p.text for p in resultOptions</wyn>。</li><li>所选行如何显示给服务器是(M)模型关注的问题。因此,<wyn>ng-options</wyn>提供<wyn>as</wyn>关键字来指定在<wyn>k as v for (k,v) in objects</wyn>中为模型提供的值。</li></ul><P>正确的解决方案这个问题本质上就是体系结构,它涉及到重构HTML,以便(M)模型在需要时(而不是用户提交表单)执行服务器通信。</P><P>如果对于手头的问题,MVC HTML页面不需要过于工程化:那么只使用AngularJS(v)IEW组件的HTML生成部分。在这种情况下,按照与生成诸如<wyn><ul /></wyn>下的<wyn><li /></wyn>等元素相同的模式,在选项元素上放置一个ng repeat:</P>[cc lang="javascript"]<select name="value"> <option ng-repeat="value in Model.Values" value="{{value.value}}"> {{value.text}} </option> </select> |
作为组合,可以始终将select元素的name属性移动到隐藏的输入元素:
1 2 3 | <select ng-model="selectedValue" ng-options="value.text for value in Model.Values"> </select> <input type="hidden" name="value" value="{{selectedValue}}" /> |
您可以这样做:
1 2 3 4 | <select ng-model="model"> <option value="">Select</option> <option ng-repeat="obj in array" value="{{obj.id}}">{{obj.name}}</option> </select> |
——更新
经过一些更新,用户frm.adiputra的解决方案要好得多。代码:
1 2 | obj = { '1': '1st', '2': '2nd' }; <select ng-options="k as v for (k,v) in obj"></select> |
我今天在这个问题上挣扎了一段时间。我通读了AngularJS的文档、这篇文章和其他一些文章,以及他们的一些博客。他们都帮助我摸索出更细微的细节,但最终这似乎是一个令人困惑的话题。主要是由于
最后,对我来说,它归结为"越少越好"。
给定的作用域配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //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 }; |
这就是我获得想要的结果所需要的全部:
1 2 3 4 | <select ng-model="rec.FirmnessID" ng-options="g.FirmnessID as g.Description for g in list"> <option></option> </select> |
注意我没有使用
此外,我需要空白的第一行,所以我简单地将EDCOX1的4个Ed添加到EDCOX1的5个元素。
这是一个展示我工作的工具。
Instead of using the new 'track by' feature you can simply do this with an array if you want the values to be the same as the text:
1 | <select ng-options="v as v for (k,v) in Array/Obj"></select> |
请注意标准语法之间的差异,标准语法将使值成为对象/数组的键,因此数组的键为0、1、2等:
1 | <select ng-options"k as v for (k,v) in Array/Obj"></select> |
K作为V变成V作为V。
我发现这仅仅是基于对语法的常识。(k,v)是将数组/对象拆分为键值对的实际语句。
在"k as v"语句中,k是值,v是向用户显示的文本选项。我认为"跟踪"是凌乱和过度杀戮。
根据我的说法,这最适合所有场景:
1 2 3 4 | <select ng-model="mySelection.value"> <option ng-repeat="r in myList" value="{{r.Id}}" ng-selected="mySelection.value == r.Id">{{r.Name}} </option> </select> |
您可以在其中使用模型绑定数据。您将获得对象将包含的值以及基于您的方案的默认选择。
这就是我解决这个问题的方法。我跟踪了select by值,并在我的javascript代码中将selected item属性设置为模型。
1 2 3 4 5 6 7 8 9 | Countries = [ { CountryId = 1, Code = 'USA', CountryName = 'United States of America' }, { CountryId = 2, Code = 'CAN', CountryName = 'Canada' } ] |
1 | <select ng-model="vm.Enterprise.AdminCountry" ng-options="country.CountryName for country in vm.Countries track by country.CountryId"> |
当我从"选择"下拉列表中选择另一个国家并用"保存"发布我的页面时,我得到了正确的国家边界。
使用
set the
's label as limit.text
save thelimit.value value into the select'sng-model
请参见堆栈溢出问题AngularJS NG选项而不是呈现值。
1 | <select ng-model="color" ng-options="(c.name+' '+c.shade) for c in colors"></select> |
问题一年后,我必须找到这个问题的答案,因为这些答案中的一个至少给了我实际的答案。
你问过如何选择选项,但没有人说这两件事不一样:
If we have an options like this:
1 2 3 4 | $scope.options = [ { label: 'one', value: 1 }, { label: 'two', value: 2 } ]; |
我们尝试设置一个这样的默认选项:
1 | $scope.incorrectlySelected = { label: 'two', value: 2 }; |
它将不起作用,但如果您尝试选择如下选项:
1 | $scope.correctlySelected = $scope.options[1]; |
它会起作用的。
尽管这两个对象具有相同的属性,但AngularJS认为它们是不同的,因为AngularJS通过引用进行比较。
看看小提琴http://jsfiddle.net/qwztb/。
根据设置数据源的方式,在ng选项中选择一个项目可能有点困难。
经过一段时间的挣扎,我最终用我使用的最常见的数据源制作了一个样本。你可以在这里找到它:
http://plnkr.co/edit/fgq2pm?P=预览
现在要使ng选项起作用,需要考虑以下几点:
- 状态::ng选项的数据
- user.state::设置为选中的选项
设置下拉/选择控件值的方式取决于3,
- 如果下拉键是单个属性(如punkr中的所有示例),则只需设置它,例如:
$scope.dropdownmodel = $scope.user.state; 如果将对象设置为键,则需要通过选项循环,即使指定对象也不会将项目设置为选中,因为它们将具有不同的哈希键,例如:
1
2
3
4
5
6
7for (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;
}
}
您可以在另一个对象
对我来说,布鲁诺·戈麦斯的回答是最好的答案。
但实际上,您不必担心设置select选项的value属性。安古拉吉斯会处理好的。让我详细解释一下。
请考虑一下这个小提琴
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 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或任何其他库访问该选择组合框选项的值并对其进行相应的操作,否则在输出中并不重要。
可以使用ng选项实现对值和显示成员的选择标记绑定
使用此数据源时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | countries : [ { "key": 1, "name":"UAE" }, { "key": 2, "name":"India" }, { "key": 3, "name":"OMAN" } ] |
可以使用下面的命令将所选标记绑定到值和名称
1 | <select name="text" ng-model="name" ng-options="c.key as c.name for c in countries"></select> |
它工作得很好
用户frm.adiputra提供了对此问题的正确答案,因为目前这似乎是显式控制选项元素的value属性的唯一方法。
然而,我只是想强调"select"在这个上下文中不是关键字,而是表达式的占位符。有关"select"表达式以及其他可在ng options指令中使用的表达式的定义,请参阅以下列表。
使用问题中描述的select:
1 | ng-options='select p.text for p in resultOptions' |
基本上是错误的。
根据表达式列表,在对象数组中给定选项时,似乎可以使用trackexpr来指定值,但仅用于分组。
从AngularJS关于NG选项的文档中:
- 数组/对象:计算为数组/对象的表达式迭代。
- 值:局部变量,它将引用迭代期间对象的数组或每个属性值。
- 键:局部变量,在迭代。
- label:此表达式的结果将是元素。表达式很可能引用该值变量(例如value.propertyname)。
- 选择:此表达式的结果将绑定到父元素的模型。如果未指定,select表达式将默认为value。
- group:此表达式的结果将用于使用dom对选项进行分组元素。
- trackexpr:在处理对象数组时使用。将使用此表达式的结果以标识数组中的对象。trackexpr很可能引用值变量(例如value.propertyname)。
请使用Track By属性来区分选择框中的值和标签。
请尝试
1 | <select ng-options="obj.text for obj in array track by obj.value"></select> |
它将用文本指定标签,用值指定值(从数组中)
对于开发人员来说,使用NG选项总是很痛苦的。例如:获取select标记中的空/空选定值。尤其是在NG选项中处理JSON对象时,它会变得更加乏味。在这里我做了一些练习。
目标:通过ng选项迭代JSON对象数组,并设置所选的第一个元素。
数据:
1 2 | someNames = [{"id":"1","someName":"xyz <hr><P>对象:</P>[cc lang="javascript"]<select ng-model="mySelect" ng-options="key as value for (key, value) in object"></select> |
教程angular.js:ng-select和ng-options帮助我解决了这个问题:
1 2 3 4 | <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> |
运行代码段并查看变体。这是快速理解的注释
例1(对象选择):-
ng-model="my_os" 应设置为键为id的对象,如my_os={id: 2} 。
例2(值选择):-
ng-model="my_os" 应设置为与my_os= 2 类似的值。
REST代码片段将解释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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); }) |
1 2 3 4 5 6 | fieldset{ margin-bottom: 40px; } strong{ color:red; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.10/angular.min.js"> <!--//************ EXAMPLE 1 *******************--> <fieldset> <legend>Example 1 (Set selection as object)</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 value. 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> |
1 2 3 | <select ng-model="output"> <option ng-repeat="(key,val) in dictionary" value="{{key}}">{{val}}</option> </select> |
就像很多人之前说的,如果我有这样的数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | countries : [ { "key": 1, "name":"UAE" }, { "key": 2, "name":"India" }, { "key": 3, "name":"OMAN" } ] |
我会像这样使用它:
1 2 3 4 | <select ng-model="selectedCountry" ng-options="obj.name for obj in countries"> </select> |
在控制器中,需要设置一个初始值以除去第一个空项:
1 2 3 4 5 6 7 8 9 10 11 12 13 | $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中:1 | ng-options="kitType.name for kitType in vm.kitTypes track by kitType.id" ng-model="vm.itemTypeId" |
在JavaScript中:
1 2 3 | vm.kitTypes = [ {"id":"1","name":"Virtual <hr>NGOPTIONS指令:[cc lang="javascript"]$scope.items = [{name: 'a', age: 20},{ name: 'b', age: 30},{ name: 'c', age: 40}]; |
case-1)数组中值的标签:
1
2
3
4
5
6
7
8<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>
输出说明(假设选择了第一项):
selected item=name:'a',age:20//[默认情况下,所选项等于值项]
selectedItem.age=20
case-2)选择作为数组中的值的标签:
1
2
3
4
5<p>
selected item is : {{selectedItem}}
</p>
<select ng-model="selectedItem" ng-options="item.age as item.name for item in items">
</select>
输出说明(假设选择了第一项):selecteditem=20//[选择部件为item.age]