这似乎是困扰很多人(包括我) .
在AngularJS中使用 ng-options
指令填写 <select>
标签的选项时,我无法弄清楚如何设置选项的值 . 这方面的文档真的不清楚 - 至少对像我这样的傻瓜来说 .
我可以像这样轻松设置选项的文本:
ng-options="select p.text for p in resultOptions"
以 resultOptions
为例:
[
{
"value": 1,
"text": "1st"
},
{
"value": 2,
"text": "2nd"
}
]
它应该(并且可能是)设置选项值最简单的事情,但到目前为止我还没有得到它 .
27 回答
对我来说the answer by Bruno Gomes是最好的答案 .
但实际上,您无需担心设置选项的值属性 . AngularJS将负责这一点 . 让我详细解释一下 .
Please consider this fiddle
正如您在小提琴输出中看到的,无论您为选择框选项选择什么,它都是您的自定义值,或AngularJS的0,1,2自动生成值,除非您使用jQuery或任何其他输出,否则它在您的输出中无关紧要其他库访问该选择组合框选项的值并相应地操作它 .
教程ANGULAR.JS: NG-SELECT AND NG-OPTIONS帮我解决了这个问题:
今天我一直在努力解决这个问题 . 我通读了AngularJS文档,这篇以及其他帖子和他们引导的一些博客 . 他们都帮助我克服了更精细的细节,但最终这似乎是一个令人困惑的话题 . 主要是因为
ng-options
的许多句法细微差别 .最后,对我来说,更少的是它 .
给定范围配置如下:
这就是我获得所需结果所需的全部内容:
注意我没有使用
track by
. 使用track by
所选项目将始终返回与FirmnessID匹配的对象,而不是FirmnessID本身 . 这现在符合我的标准,即它应该返回一个数值而不是对象,并使用ng-options
通过不为生成的每个选项创建新范围来获得它提供的性能改进 .另外,我需要空白的第一行,所以我只是将
<option>
添加到<select>
元素 .这是一个显示我工作的Plunkr .
对于一个对象:
如果您希望值与文本相同,则可以使用数组执行此操作,而不是使用新的“跟踪依据”功能:
注意标准语法之间的区别,它将使值成为Object / Array的键,因此数组为0,1,2等:
k为v,v为v .
我发现这只是基于常识来看语法 . (k,v)是将数组/对象拆分为键值对的实际语句 .
在'k as v'语句中,k将是值,v将是显示给用户的文本选项 . 我认为'追踪'是凌乱和矫枉过正的 .
ng-options
指令未在数组的<options>
元素上设置value属性:使用
limit.value as limit.text for limit in limits
表示:请参阅Stack Overflow问题AngularJS ng-options not rendering values .
要使用普通表单提交将名为
my_hero
的自定义值发送到服务器:JSON:
HTML:
服务器将收到
iron
或super
作为my_hero
的值 .这与the answer by @neemzy类似,但为
value
属性指定单独的数据 .开发人员使用ng-options总是很痛苦 . 例如:在select标记中获取空/空选定值 . 特别是在ng-options中处理JSON对象时,它变得更加乏味 . 在这里,我做了一些练习 .
目标:通过ng-option迭代JSON对象数组并设置选定的第一个元素 .
数据:
在select标签中我必须显示xyz和abc,其中必须毫不费力地选择xyz .
HTML:
通过上面的代码示例,您可能会摆脱这种夸张 .
另一个reference:
问题发生一年后,我不得不为这个问题找到答案,因为其中没有给出实际答案,至少对我来说 .
您已经询问如何选择该选项,但没有人说这两件事情是相同的: NOT
如果我们有这样的选项:
我们尝试设置这样的默认选项:
它将 NOT 工作,但如果您尝试选择这样的选项:
它会 WORK .
即使这两个对象具有相同的属性,AngularJS也将它们视为不同,因为AngularJS比较了 reference .
看看小提琴http://jsfiddle.net/qWzTb/ .
这就是我解决这个问题的方法 . 我跟踪了select by value,并在JavaScript代码中将所选的item属性设置为模型 .
vm
是我的控制器,从服务中检索到的控制器中的国家/地区是{CountryId =1, Code = 'USA', CountryName='United States of America'}
.当我选择另一个国家从选择下拉列表和我的页面“保存”,我得到了正确的国家/地区 .
如果要更改
option
元素的值,因为表单最终会提交给服务器,而不是这样做,你可以这样做:
然后,预期值将通过表单以正确的名称发送 .
根据您设置数据源的方式,在ng-options中选择项目可能有点棘手 .
在与他们挣扎了一段时间后,我最终使用我使用的最常见数据源制作样本 . 你可以在这里找到它:
http://plnkr.co/edit/fGq2PM?p=preview
现在要使ng-options工作,需要考虑以下事项:
通常,您可以从一个源获取选项,从另一个源获取所选值 . 例如:
states :: ng-options的数据
user.state ::选项设置为已选中
基于1,最简单/逻辑的做法是用一个源填充选择,然后通过代码设置选定的值 . 获得混合数据集很少会更好 .
AngularJS允许选择控件保持多于
key | label
. 许多在线示例将对象设置为'key',如果您需要来自对象的信息,请以此方式设置,否则请使用您需要的特定属性作为键 . (ID,CODE等 . 如plckr样本中所示)设置下拉/选择控件值的方法取决于#3,
如果下拉键是单个属性(如plunkr中的所有示例中所示),则只需设置它,例如:
$scope.dropdownmodel = $scope.user.state;
如果将对象设置为键,则需要循环选项,即使分配对象也不会将项设置为选中,因为它们将具有不同的哈希键,例如:
您可以将savedValue替换为另一个对象
$scope.myObject.myProperty
中的相同属性 .在你的情况下,它应该是
更新
通过AngularJS上的更新,现在可以使用
track by
表达式设置select
元素的value
属性的实际值 .如何记住这些丑陋的东西
对于所有难以记住这种语法形式的人:我同意这不是最简单或最美妙的语法 . 这种语法是Python列表推导的扩展版本,并且知道这有助于我很容易地记住语法 . 它是这样的:
Python代码:
这实际上与上面列出的第一个语法相同 . 但是,在
<select>
中,我们通常需要区分代码中的实际值和<select>
元素中显示的文本(标签) .比如,我们在代码中需要
person.id
,但我们不想向用户显示id
;我们想要显示它的名字 . 同样,我们对代码中的person.name
不感兴趣 . 有标签的as
关键字 . 所以它变成这样:或者,而不是
person.id
,我们可能需要person
实例/引用本身 . 见下文:对于JavaScript对象,也适用相同的方法 . 请记住,对象中的项目是使用
(key, value)
对解构的 .值属性如何获得其值:
当使用数组作为数据源时,它将是每次迭代中数组元素的索引;
使用对象作为数据源时,它将是每次迭代中的属性名称 .
所以在你的情况下它应该是:
以下是我在遗留应用程序中解决此问题的方法:
在HTML中:
在JavaScript中:
...
我的HTML正确显示选项值 .
根据我的说法,这最适合所有场景:
您可以在哪里使用模型来绑定数据 . 您将获得对象将包含的值以及基于您的方案的默认选择 .
我也有这个问题 . 我无法在ng-options中设置我的值 . 生成的每个选项都设置为0,1,...,n .
为了使它正确,我在ng-options中做了类似的事情:
HTML:
我使用"track by"将所有值设置为
room.price
.(这个例子很糟糕:因为如果有多个价格相等,代码就会失败 . 所以要确保有不同的 Value . )
JSON:
我是从博客文章How to set the initial selected value of a select element using Angular.JS ng-options & track by中学到的 .
观看视频 . 这是一个很好的课程:)
这个问题的正确答案是provided by user frm.adiputra,因为目前这似乎是明确控制选项元素的value属性的唯一方法 .
但是,我只是想强调“select”在这个上下文中不是关键字,但它只是表达式的占位符 . 有关“select”表达式以及其他表达式的定义,请参阅以下列表可以在ng-options指令中使用的表达式 .
在问题中描述了select的使用:
本质上是错误的 .
基于表达式列表,当在对象数组中给出选项时,似乎可以使用 trackexpr 来指定值,但它仅用于分组 .
来自AngularJS的ng-options文档:
array / object :一个表达式,其求值为要迭代的数组/对象 .
value :局部变量,它将引用数组中的每个项目或迭代期间对象的每个属性值 .
key :局部变量,它将在迭代期间引用对象中的属性名称 .
label :此表达式的结果将是元素的标签 . 表达式很可能是指值变量(例如value.propertyName) .
select :此表达式的结果将绑定到父元素的模型 . 如果未指定,则select expression将默认为value .
group :此表达式的结果将用于使用DOM元素对选项进行分组 .
trackexpr :处理对象数组时使用 . 此表达式的结果将用于标识数组中的对象 . trackexpr很可能会引用值变量(例如value.propertyName) .
ngOptions指令:
输出说明(假设选择了第1项):
selectedItem = {name:'a',age:20} // [默认情况下,所选项目等于值 item ]
selectedItem.age = 20
输出说明(假设选择了第1项):selectedItem = 20 // [选择部分是 item.age ]
像之前说的那样,如果我有这样的数据:
我会用它像:
在你的Controller中你需要设置一个初始值来摆脱第一个空项目:
你可以这样做:
经过一些更新后,user frm.adiputra's solution要好得多 . 码:
您可以使用ng-options来实现选择标记绑定到值和显示成员
使用此数据源时
您可以使用以下内容将您的选择标记绑定到值和名称
它很棒
运行代码段并查看变体 . 这是为了快速理解的注意事项
示例1(对象选择): -
ng-option="os.name for os in osList track by os.id"
. 这里track by os.id
很重要os.id as
,os.id as
should NOT 之前os.name
.ng-model="my_os"
应设置为一个对象,其键为 id ,如my_os={id: 2}
.示例2(值选择): -
ng-option="os.id as os.name for os in osList"
. 这里track by os.id
should NOT 在那里os.id as
should be 之前os.name
.ng-model="my_os"
应设置为my_os= 2
之类的值Rest代码片段将解释 .
It appears that ng-options is complicated (possibly frustrating) to use, but in reality we have an architecture problem.
AngularJS充当动态HTML JavaScript应用程序的MVC框架 . 虽然它的(V)iew组件确实提供HTML "templating,",但其主要目的是通过控制器将用户操作连接到模型中的更改 . 因此 the appropriate level of abstraction, from which to work in AngularJS, is that a select element sets a value in the model to a value from a query .
如何向用户呈现查询行是(V)iew的关注点,
ng-options
提供for
关键字来指示选项元素的内容应该是什么,即p.text for p in resultOptions
.如何向服务器显示所选行是(M)odel的关注点 . 因此
ng-options
提供了as
关键字来指定为模型提供的值,如k as v for (k,v) in objects
中所示 .The correct solution this is problem is then architectural in nature and involves refactoring your HTML so that the (M)odel performs server communication when required (而不是用户提交表单) .
If an MVC HTML page is unnecessary over-engineering for the problem at hand: 然后只使用AngularJS(V)iew组件的HTML生成部分 . 在这种情况下,遵循用于生成
<li />
下的<li />
元素的相同模式,并在选项元素上放置ng-repeat:作为kludge,可以始终将select元素的name属性移动到隐藏的input元素:
请使用track by property来区分选择框中的值和标签 .
请试试
这将分配带有文本和值的标签值(来自数组)