如何在AngularJS&#39中设置value属性?ng-options吗?

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

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

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

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

resultOptions为例:

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

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

461947 次浏览

看到# EYZ0

ngOptions(可选) - {comprehension_expression=} -在其中一个 以下形式:< / p > < p > # EYZ0: # EYZ0 # EYZ0 # EYZ0 # EYZ0 对于对象数据源: # EYZ0 # EYZ0 # EYZ0 # EYZ0 < / p >

对你来说,应该是

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)对解构的。

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>

- - -更新

经过一些更新后,用户< em >纳。adiputra < / em >的解决方案好多了。代码:

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

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

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

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

设置<option>的标签为limit.text
保存limit.value值到select的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文档:

  • 数组/对象:表达式,计算结果为数组/对象 李迭代。< / >
  • 价值:局部变量,它将引用中每一项 迭代过程中对象的数组或每个属性值
  • 关键:局部变量,在对象中引用属性名 李迭代。< / >
  • 标签:该表达式的结果将是的标签 元素。表达式很可能指向值 变量(例如value.propertyName).
  • . txt
  • 选择:该表达式的结果将被绑定到父元素的模型。 如果未指定,select expression将默认为value.
  • 集团:该表达式的结果将用于使用DOM对选项进行分组 李元素。< / >
  • trackexpr:在处理对象数组时使用。将使用此表达式的结果 来识别数组中的对象。trackexpr极有可能引用 value变量(例如value. propertyname).
  • . value变量

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

AngularJS是动态HTML+JavaScript应用程序的MVC框架。虽然它的(V)视图组件确实提供了HTML“模板”,但它的主要目的是通过控制器将用户操作连接到模型中的更改。因此# EYZ0。

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

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

如果一个MVC HTML页面对于手头的问题来说是不必要的过度工程:然后只使用AngularJS的(V)视图组件的HTML生成部分。在这种情况下,遵循与生成&lt;li /&gt;'s在&lt;ul /&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}}" />

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

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

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

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

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

< a href = " http://plnkr.co/edit/fGq2PM?p=preview" rel="nofollow noreferrer">http://plnkr.co/edit/fGq2PM?p =预览< / >

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

    通常情况下,您可以从一个源获取选项,从另一个源获取所选值。例如:
    • ng-options的States:: data
    • 用户。state::设置为选中的选项
    • 李< / ul > < / >
    • 基于1,最简单/合乎逻辑的做法是用一个源填充select,然后设置所选的值槽代码。很少有更好的混合数据集。
    • AngularJS允许选择控件保存超过key | label的值。许多在线示例将对象作为“key”,如果你需要来自对象的信息,就将其设置为这种方式,否则使用你需要的特定属性作为key。(ID, CODE,等等。如plckr样本)
    • 设置下拉/选择控件值的方法取决于#3,

      • 如果下拉键是一个单独的属性(就像plunkr中的所有例子一样),你只需要设置它,例如: 李# EYZ0 < / >
      • 如果你将对象设置为键,你需要循环遍历选项,即使分配对象也不会设置选定的项目,因为它们将有不同的hashkey,例如:

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

You can replace savedValue for the same property in the other object, $scope.myObject.myProperty.

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

你问过如何选择选项,但没有人说这两件事是相同的:

如果我们有这样的选项:

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

我也有这个问题。我不能在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 &设置一个select元素的初始选择值;跟踪通过< / >中学到的。

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

开发人员使用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>

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

另一个# EYZ0:

而不是使用新的'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 . js教程帮助我解决了这个问题:

<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是我的控制器,从服务中检索到的控制器中的Country是{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。使用track by,所选项目将始终返回与FirmnessID匹配的对象,而不是FirmnessID本身。这现在满足了我的标准,即它应该返回一个数值而不是对象,并且使用ng-options来获得它所提供的性能改进,因为它不为生成的每个选项创建新的作用域。

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

这里是一个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. 例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"应该设置为一个对象,键为id,如my_os={id: 2}
    • 李< / ul > < / >
    • 例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这样的值
      • 李< / ul > < / >

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

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}];
  • < p > # EYZ0

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

Output Explanation (Assume 1st item selected):

selectedItem = {name: 'a', age: 20} // [by default, selected item is equal to the value item]

selectedItem.age = 20

  • Case-2) select as label for value in array:

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

Output Explanation (Assume 1st item selected): 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>

效果很好