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

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

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

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

例如,当resultOptions为:

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

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


当前回答

这就是我解决这个问题的方法。我根据值跟踪了选择,并在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是我的控制器,从服务检索到的控制器中的国家是{CountryId =1, Code =' USA', CountryName='United States of America'}。

当我从选择下拉菜单中选择了另一个国家,并发布了“保存”页面时,我得到了正确的国家边界。

其他回答

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

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

今天我已经为这个问题纠结了一段时间。我通读了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。使用所选项的跟踪将总是返回与FirmnessID匹配的对象,而不是FirmnessID本身。这现在满足了我的标准,即它应该返回一个数值而不是对象,并且使用ng-options来获得它所提供的性能改进,而不是为生成的每个选项创建一个新的作用域。

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

这是一个展示我作品的Plunkr。

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

AngularJS是动态HTML+JavaScript应用程序的MVC框架。虽然它的(V)视图组件确实提供了HTML“模板”,但它的主要目的是通过控制器将用户操作连接到模型中的更改。因此,在AngularJS中,适当的抽象级别是select元素将模型中的值设置为来自查询的值。

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

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

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

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

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)