ChatGPT解决这个技术问题 Extra ChatGPT

如何在 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"
    }
]

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

有同样的问题,因为我没有找到非常清楚的文档(如下所示)。
问题中描述的“选择”的使用本质上是错误的,因为在这种情况下,“选择”不是关键字,而是表达式的占位符。这来自 AngularJS 的文档:“选择:此表达式的结果将绑定到父元素的模型。如果未指定,则选择表达式将默认为值。”我在下面的答案中提供了更多详细信息。
对我来说这是最好的答案。 stackoverflow.com/questions/12139152/…
注意:要使 ng-options 起作用,ng-model 是必需的!!!!!!!!!参考:stackoverflow.com/a/13049740/234110

D
Dan Atkinson

请参阅 ngOptions ngOptions(optional) – {comprehension_expression=} – 采用以下形式之一: 对于数组数据源:数组中值的标签 选择作为数组中值的标签 标签组按组为数组中的值选择标签组对于数组中的值 track by trackexpr 对于对象数据源: 对象中的 (key , value) 的标签 select as label for (key , value) in object label group by group for (key, value) 对象中的标签 按组选择对象中的(键,值)

在你的情况下,它应该是

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 实例/引用本身,而不是 person.id。见下文:

person as person.name for person in people

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


您的示例未填充选项的 value 属性。它定义了将存储在 <select> 模型中的内容。元素。查看 obj.value as obj.textobj.text 之间的区别
奇怪,但我在 Chrome 和 FF 中得到
这不是错误,这是一个功能。 angularjs 在内部处理 ngOptions 和 ngModel,这样它允许您使用任何类型的对象作为选项中的值,而不仅仅是字符串。您永远不应该尝试以其他方式获取 select 的值,您只需要使用附加到 select 元素的 ngModel 即可。
我不敢苟同。在内部,select 指令可以很容易地使用它自己的不可见模型来跟踪选择了哪个选项。即使它没有在内部跟踪模型值,它至少可以呈现选项并只是预先选择并选择空选项(如果您将模型设置为不在选项集中的值,这是现在的行为) .显示选项的唯一依赖是选项本身——这里适用 POLA 原则。
为什么这个答案没有提供答案时有这么多赞成票? frm.adiputra 的回答是正确的。
P
Peter Mortensen

值属性如何获取其值:

使用数组作为数据源时,每次迭代都会是数组元素的索引;

当使用对象作为数据源时,它将是每次迭代中的属性名称。

所以在你的情况下应该是:

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

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

+1 用于解释 Angular 如何设置选项元素的 value 属性。
这不会设置值。值默认为数字。但你实际上不能指定一个“价值”..可笑的..
@Trip,如果您“检查”选择选项,您将看到数字,但如果您查看模型中的绑定值,则在这种情况下该值是“k”值。这很令人困惑。 blesh 在这个答案中显示了这一点:stackoverflow.com/questions/13047923/… plnkr.co/edit/vJOljg?p=preview
这应该包含在角度文档中,简短而准确。 +1
这是唯一对我有用的解决方案。多么令人头疼的问题。
C
Community

我也有这个问题。我无法在 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 }
        ];

我是从博文中了解到的How to set the initial selected value of a select element using Angular.JS ng-options & track by

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


这完美地工作。最重要的是,它允许使用包含 。你所拥有的东西可以工作,但它不适用于其他 Angular 结构。例如,这个 ng-click 不适用于您的代码:select 1,但如果使用 ng-options,它确实有效。
由于这样做,我刚刚出现了一个奇怪的错误。大量痛苦的搜索使我发现了 ng-options,并且该错误消失了。 ng-model 似乎要求选项的 value 属性是数字的,并且从 0 开始递增。如果使用 ng-repeat 和
J
Jeffrey A. Gochin

我今天已经为这个问题苦苦挣扎了一段时间。我通读了 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 通过不为生成的每个选项创建新范围来获得它提供的性能改进。

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

这是显示我的工作的 Plunkr


传奇。这正是我所需要的。谢谢
很好,但是“值”键的用途是什么?它们似乎没有必要。
与示例无关。它们只是我的客户提供给我的原始数据的一部分。
K
KthProg

如果您希望值与文本相同,则无需使用新的“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 as v 变成 v as v。

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

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


哇哦?适用于我页面上各处的数组,我们使用的是相同版本的 AngularJS 吗?
P
Peter Mortensen

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

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

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


喜欢这个解决方案。他们对该指令的角度助手不必要地复杂。感谢您自称是使用情况的判断者。
P
Peter Mortensen

这就是我解决这个问题的方法。我跟踪了按值选择,并在我的 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'}

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


C
Community

ng-options 指令未在数组的 <options> 元素上设置 value 属性:

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

请参阅 Stack 溢出问题 AngularJS ng-options not rendering values


W
Wessam Al-Bakary

可以使用 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>

效果很好


请通过一些解释来增加您的纯代码答案,以避免误解 StackOverflow 是免费的代码编写服务。
A
Anja Ishmukhametova
<select ng-model="color" ng-options="(c.name+' '+c.shade) for c in colors"></select><br>

A
Aleks

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

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

如果我们有这样的选择:

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


C
Community

这个问题的正确答案是 provided by user frm.adiputra,因为目前这似乎是显式控制选项元素的 value 属性的唯一方法。

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

问题中描述的 select 的使用:

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

本质上是错误的。

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

来自 AngularJS 的 ng-options 文档:

数组/对象:计算结果为要迭代的数组/对象的表达式。

value:局部变量,将在迭代期间引用数组中的每个项目或对象的每个属性值。

key:局部变量,在迭代期间将引用对象中的属性名称。

标签:此表达式的结果将是元素的标签。表达式很可能引用值变量(例如 value.propertyName)。

select:此表达式的结果将绑定到父元素的模型。如果未指定,则选择表达式将默认为值。

group:此表达式的结果将用于使用 DOM 元素对选项进行分组。

trackexpr:在处理对象数组时使用。此表达式的结果将用于识别数组中的对象。 trackexpr 很可能会引用 value 变量(例如 value.propertyName)。


P
Peter Mortensen

根据您设置数据源的方式,在 ng-options 中选择一个项目可能会有些棘手。

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

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

现在要使 ng-options 工作,这里有一些事情需要考虑:

通常,您从一个来源获得选项,从另一个来源获得选定的值。例如:states :: data for ng-options user.state :: 选项设置为选中 基于 1,最简单/合乎逻辑的做法是用一个源填充选择,然后通过代码设置所选值。获得混合数据集很少会更好。 AngularJS 允许选择控件持有多个键 |标签。许多在线示例将对象作为“键”,如果您需要来自对象的信息,请按此方式设置,否则使用您需要的特定属性作为键。 (ID、CODE 等。如在 plckr 示例中)设置下拉/选择控件值的方式取决于 #3,如果下拉键是单个属性(如 plunkr 中的所有示例),您只需设置它,例如:$scope.dropdownmodel = $scope.user.state;如果将对象设置为键,则需要循环通过选项,即使分配对象也不会将项目设置为选中,因为它们将具有不同的哈希键,例如:for (var i = 0, len = $scope.options. length; i < len; i++) { if ($scope.options[i].id == savedValue) { // 这里是你自己的属性:console.log('Found target!'); $scope.value = $scope.options[i];休息; } }

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


多年后,我感谢您提供的 plunker 样品。很有用。
C
Community

对我来说the answer by Bruno Gomes是最好的答案。

但实际上,您不必担心设置选择选项的 value 属性。 AngularJS 会解决这个问题。让我详细解释一下。

Please consider this fiddle

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 或任何其他库来访问该选择组合框选项的值并相应地对其进行操作。


S
Shashank Saxena

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

请试试

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

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


E
EpokK

对于一个对象:

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

C
Community

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

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

另一个reference


P
Peter Mortensen

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

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

ngOptions 提供了一些好处,例如通过不为每个重复实例创建新范围来减少内存和提高速度,请参阅:docs.angularjs.org/api/ng/directive/ngOptions
P
Premchandra Singh

运行代码片段并查看变化。这是快速理解的注释

示例 1(对象选择):- ng-option="os.name for os in osList track by os.id"。这里通过 os.id 进行跟踪很重要,应该存在,并且 os.id 在 os.name 之前不应该有。 ng-model="my_os" 应该设置为一个对象,其键为 id,如 my_os={id: 2}。示例 2(值选择):- ng-option="os.id as os.name for os in osList"。这里不应该有 os.id 的跟踪,而 os.id 应该在 os.name 之前。 ng-model="my_os" 应该设置为类似 my_os= 2 的值

其余代码片段将解释。

angular.module('app', []).controller('ctrl', function($scope, $timeout){ //************ 示例 1 ******* ************ $scope.osList =[ { id: 1, name :'iOS'}, { id: 2, name :'Android'}, { id: 3, name :' Windows'} ] $scope.my_os = {id: 2}; //************ 示例 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; } 强{ 颜色:红色; }

< legend>Example 1 (Set selection as object) {{my_os}}
示例2(设置选择为value。模拟ajax) {{my_site}}


P
Peter Mortensen

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

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)

P
Peter Mortensen

以下是我在遗留应用程序中解决此问题的方法:

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


M
Masud Shrabon

ngOptions 指令:

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

Case-1) 数组中值的标签:

所选项目为:{{selectedItem}}

所选项目的年龄为:{{selectedItem.age}}

< select ng-model="selectedItem" ng-options="item.name for item in items">

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

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

selectedItem.age = 20

案例2)选择作为数组中值的标签:

所选项目是:{{selectedItem}}

输出说明(假设第一个项目被选中): selectedItem = 20 // [选择部分是 item.age]