首页 文章

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

提问于
浏览
533

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

在AngularJS中使用 ng-options 指令填写 <select> 标签的选项时,我无法弄清楚如何设置选项的值 . 这方面的文档真的不清楚 - 至少对像我这样的傻瓜来说 .

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

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

resultOptions 为例:

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

它应该(并且可能是)设置选项值最简单的事情,但到目前为止我还没有得到它 .

27 回答

  • 25

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

    但实际上,您无需担心设置选项的值属性 . 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或任何其他输出,否则它在您的输出中无关紧要其他库访问该选择组合框选项的值并相应地操作它 .

  • 19

    教程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>
    
  • 7
    <select ng-model="output">
       <option ng-repeat="(key,val) in dictionary" value="{{key}}">{{val}}</option>
    </select>
    
  • 3

    今天我一直在努力解决这个问题 . 我通读了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 .

  • 3

    对于一个对象:

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

    如果您希望值与文本相同,则可以使用数组执行此操作,而不是使用新的“跟踪依据”功能:

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

    注意标准语法之间的区别,它将使值成为Object / Array的键,因此数组为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将是显示给用户的文本选项 . 我认为'追踪'是凌乱和矫枉过正的 .

  • 3

    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 not rendering values .

  • 2

    要使用普通表单提交将名为 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 的值 .

    这与the answer by @neemzy类似,但为 value 属性指定单独的数据 .

  • 13

    开发人员使用ng-options总是很痛苦 . 例如:在select标记中获取空/空选定值 . 特别是在ng-options中处理JSON对象时,它变得更加乏味 . 在这里,我做了一些练习 .

    目标:通过ng-option迭代JSON对象数组并设置选定的第一个元素 .

    数据:

    someNames = [{"id":"1", "someName":"xyz"}, {"id":"2", "someName":"abc"}]
    

    在select标签中我必须显示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

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

    问题发生一年后,我不得不为这个问题找到答案,因为其中没有给出实际答案,至少对我来说 .

    您已经询问如何选择该选项,但没有人说这两件事情是相同的: NOT

    如果我们有这样的选项:

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

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

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

    它将 NOT 工作,但如果您尝试选择这样的选项:

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

    它会 WORK .

    即使这两个对象具有相同的属性,AngularJS也将它们视为不同,因为AngularJS比较了 reference .

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

  • 2

    这就是我解决这个问题的方法 . 我跟踪了select by value,并在JavaScript代码中将所选的item属性设置为模型 .

    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'} .

    当我选择另一个国家从选择下拉列表和我的页面“保存”,我得到了正确的国家/地区 .

  • 671

    如果要更改 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 }}" />
    

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

  • 0

    根据您设置数据源的方式,在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;

    • 如果将对象设置为键,则需要循环选项,即使分配对象也不会将项设置为选中,因为它们将具有不同的哈希键,例如:

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

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

  • 10

    请参阅ngOptions ngOptions(可选) - - 使用以下形式之一:对于数组数据源:数组中值的标签选择为数组标签中值的标签按组排列的值选择作为标签组的值通过trackexpr对数组轨道中的值进行分组对于对象数据源:对象中的(键,值)标签选择对象标签中的(键,值)标签按对象中的(键,值)组选择作为标签组的对象中的(键,值)组

    在你的情况下,它应该是

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

  • 132

    值属性如何获得其值:

    • 当使用数组作为数据源时,它将是每次迭代中数组元素的索引;

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

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

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

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

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

  • 2

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

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

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

  • 46

    我也有这个问题 . 我无法在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 .

    (这个例子很糟糕:因为如果有多个价格相等,代码就会失败 . 所以要确保有不同的 Value . )

    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中学到的 .

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

  • 23

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

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

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

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

    本质上是错误的 .

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


    来自AngularJS的ng-options文档:

    • array / object :一个表达式,其求值为要迭代的数组/对象 .

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

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

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

    • select :此表达式的结果将绑定到父元素的模型 . 如果未指定,则select expression将默认为value .

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

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

  • 9

    ngOptions指令:

    $scope.items = [{name: 'a', age: 20},{ name: 'b', age: 30},{ name: 'c', age: 40}];
    
    • Case-1) label for value in array:
    <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>
    

    输出说明(假设选择了第1项):

    selectedItem = {name:'a',age:20} // [默认情况下,所选项目等于值 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>
    

    输出说明(假设选择了第1项):selectedItem = 20 // [选择部分是 item.age ]

  • 8

    像之前说的那样,如果我有这样的数据:

    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>
    

    在你的Controller中你需要设置一个初始值来摆脱第一个空项目:

    $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)
    
  • 3

    你可以这样做:

    <select ng-model="model">
        <option value="">Select</option>
        <option ng-repeat="obj in array" value="{{obj.id}}">{{obj.name}}</option>
    </select>
    
    • 更新

    经过一些更新后,user frm.adiputra's solution要好得多 . 码:

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

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

    它很棒

  • 0

    运行代码段并查看变体 . 这是为了快速理解的注意事项

    • 示例1(对象选择): - ng-option="os.name for os in osList track by os.id" . 这里 track by os.id 很重要 os.id asos.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代码片段将解释 .

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

    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生成部分 . 在这种情况下,遵循用于生成 &lt;li /&gt; 下的 &lt;li /&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}}” />
    
  • 2

    请使用track by property来区分选择框中的值和标签 .

    请试试

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

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

相关问题