使用 AngularJS 的 ng-options 进行选择

IT技术 javascript angularjs html-select ng-options
2021-01-29 03:51:04

我在其他帖子中读到过它,但我无法弄清楚。

我有一个数组,

$scope.items = [
   {ID: '000001', Title: 'Chicago'},
   {ID: '000002', Title: 'New York'},
   {ID: '000003', Title: 'Washington'},
];

我想将其呈现为:

<select>
  <option value="000001">Chicago</option>
  <option value="000002">New York</option>
  <option value="000003">Washington</option>
</select>

而且我还想选择 ID=000002 的选项。

我已经阅读了选择并尝试过,但我无法弄清楚。

6个回答

需要注意的一件事是 ngModel 是ngOptions 工作必需的......注意ng-model="blah"它说“将 $scope.blah 设置为选定的值”。

试试这个:

<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>

这里有更多来自 AngularJS 的文档(如果你还没有看过):

对于数组数据源:

  • 数组中值的标签
  • 选择作为数组中值的标签
  • 标签 group by group for value in array = 选择作为标签 group by group for value in array

对于对象数据源:

  • 对象中(键,值)的标签
  • 选择作为对象中 (key , value) 的标签
  • 对象中的(键,值)的标签分组
  • 为对象中的(键,值)按组选择作为标签

关于 AngularJS 中选项标签值的一些说明:

当您使用 时ng-options由 ng-options 写出的选项标签的值将始终是选项标签相关的数组项的索引这是因为 AngularJS 实际上允许您使用选择控件选择整个对象,而不仅仅是原始类型。例如:

app.controller('MainCtrl', function($scope) {
   $scope.items = [
     { id: 1, name: 'foo' },
     { id: 2, name: 'bar' },
     { id: 3, name: 'blah' }
   ];
});
<div ng-controller="MainCtrl">
   <select ng-model="selectedItem" ng-options="item as item.name for item in items"></select>
   <pre>{{selectedItem | json}}</pre>
</div>

以上将允许您直接选择整个对象$scope.selectedItem关键是,使用 AngularJS,您无需担心选项标签中的内容。让 AngularJS 来处理;您应该只关心您的范围内模型中的内容。

这是一个演示上述行为的plunker,并显示写出的HTML


处理默认选项:

上面有几件事我没有提到与默认选项有关。

选择第一个选项并删除空选项:

您可以通过添加一个简单的方法ng-init将模型 (from ng-model) 设置为您重复的项目中的第一个元素ng-options

<select ng-init="foo = foo || items[0]" ng-model="foo" ng-options="item as item.name for item in items"></select>

注意:如果foo碰巧正确初始化为“falsy”,这可能会变得有点疯狂在这种情况下,您foo很可能希望在控制器中处理 的初始化

自定义默认选项:

这有点不同;在这里,您需要做的就是添加一个选项标签作为您选择的子项,使用空值属性,然后自定义其内部文本:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="">Nothing selected</option>
</select>

注意:在这种情况下,即使您选择了不同的选项,“空”选项也会保留在那里。这不是 AngularJS 下选择的默认行为的情况。

进行选择后隐藏的自定义默认选项:

如果您希望在选择一个值后您的自定义默认选项消失,您可以将 ng-hide 属性添加到您的默认选项:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="" ng-if="foo">Select something to remove me.</option>
</select>
是否可以避免第一个空选项 ( <option value="?" selected="selected"></option>)?
2021-03-16 03:51:04
“...ngModel 需要 ngOptions 才能工作...”对我来说是问题的症结所在。好答案。
2021-03-21 03:51:04
我正在尝试使用最后一种情况(进行选择后隐藏的自定义默认选项),但我发现了一些问题。如果选择其他选项时ng-if="foo"我必须使用ng-if=!foo以隐藏默认的空选项。此外,默认的空选项总是出现在组合列表的底部。我怎么能把它放在组合列表的开头?
2021-03-24 03:51:04
文档位于他们网站上的“选择”下:docs.angularjs.org/api/ng.directive : select
2021-04-05 03:51:04
事实证明,这些是值的索引,这就是 angular 允许您使用对象作为选择框的值的方式。Angular 在幕后为你做了很多选择框的事情,你不应该担心你的选项的 value 属性。
2021-04-07 03:51:04

我正在学习 AngularJS 并且也在选择方面苦苦挣扎。我知道这个问题已经得到了回答,但我还是想分享更多的代码。

在我的测试中,我有两个列表框:汽车品牌和汽车模型。模型列表被禁用,直到选择了某些品牌。如果之后在制造列表框中的选择被重置(设置为“选择制造”),那么模型列表框将再次被禁用并且它的选择也被重置(为“选择模型”)。制造商作为资源检索,而模型只是硬编码。

生成 JSON:

[
{"code": "0", "name": "Select Make"},
{"code": "1", "name": "Acura"},
{"code": "2", "name": "Audi"}
]

服务.js:

angular.module('makeServices', ['ngResource']).
factory('Make', function($resource){
    return $resource('makes.json', {}, {
        query: {method:'GET', isArray:true}
    });
});

HTML文件:

<div ng:controller="MakeModelCtrl">
  <div>Make</div>
  <select id="makeListBox"
      ng-model="make.selected"
      ng-options="make.code as make.name for make in makes"
      ng-change="makeChanged(make.selected)">
  </select>

  <div>Model</div>
  <select id="modelListBox"
     ng-disabled="makeNotSelected"
     ng-model="model.selected"
     ng-options="model.code as model.name for model in models">
  </select>
</div>

控制器.js:

function MakeModelCtrl($scope)
{
    $scope.makeNotSelected = true;
    $scope.make = {selected: "0"};
    $scope.makes = Make.query({}, function (makes) {
         $scope.make = {selected: makes[0].code};
    });

    $scope.makeChanged = function(selectedMakeCode) {
        $scope.makeNotSelected = !selectedMakeCode;
        if ($scope.makeNotSelected)
        {
            $scope.model = {selected: "0"};
        }
    };

    $scope.models = [
      {code:"0", name:"Select Model"},
      {code:"1", name:"Model1"},
      {code:"2", name:"Model2"}
    ];
    $scope.model = {selected: "0"};
}
@DmitriZaitsev 我认为您错了,仅仅因为 angular docs 示例以您描述的方式显示它并不意味着这是唯一的方法。告诉我们为什么你认为它不应该以这种方式使用,而不是为新手提供一个很好的例子。
2021-03-15 03:51:04
亲爱的随机用户。虽然这个问题及其答案相当简单和不复杂,但您将代码组织到其正确和各自的位置(控制器、服务、模板、数据)以最简单和默认的形式展示了 AngularJS 的优雅。很棒的例子。
2021-03-16 03:51:04
这不是它的用途。ng-model应该指向作用域上的另一个变量,与make. 请参阅docs.angularjs.org/api/ng/directive/ngOptions 中的示例
2021-03-16 03:51:04

出于某种原因,AngularJS 让我感到困惑。他们的文档在这方面非常糟糕。将欢迎更多好的变化示例。

无论如何,我对 Ben Lesh 的回答略有不同。

我的数据集合如下所示:

items =
[
   { key:"AD",value:"Andorra" }
,  { key:"AI",value:"Anguilla" }
,  { key:"AO",value:"Angola" }
 ...etc..
]

现在

<select ng-model="countries" ng-options="item.key as item.value for item in items"></select>

仍然导致选项值成为索引(0、1、2 等)。

添加Track By为我修复了它:

<select ng-model="blah" ng-options="item.value for item in items track by item.key"></select>

我认为您想要将一组对象添加到选择列表中的情况更常见,所以我会记住这个!

请注意,从 AngularJS 1.4 开始,您不能再使用 ng-options,但您需要ng-repeat在选项标签上使用:

<select name="test">
   <option ng-repeat="item in items" value="{{item.key}}">{{item.value}}</option>
</select>
应该指出的是,这在模型中存储了完整的选定对象,而不仅仅是键。如果你只想要模型中的键,你想使用“item.key as item.value”版本。这让我困惑了一段时间,因为我一直在关注 HTML 的外观,而不是我想要的模型中的数据,这对我来说很重要。
2021-03-11 03:51:04
关于更新,这看起来不对。ng-options 在 1.5 中仍然可以正常工作。它也仍然显示在文档中。 docs.angularjs.org/api/ng/directive/select
2021-03-12 03:51:04
我们如何检测内部带有“ng-change”的变化option
2021-03-18 03:51:04
@mhenry1384 是的,你是对的,关于它存储整个对象。我真的很喜欢这个功能,因为它不仅能让你访问 ID(如果你需要的话)。当我使用 mongo 集合填充列表并且我需要所选项目的一些属性时,这对我来说效果很好。
2021-03-19 03:51:04
这个答案似乎正是问题所要求的。每个其他答案都告诉读者不要担心生成什么 HTML,但是如果 select 元素在表单中,我很担心。很好的答案!
2021-04-05 03:51:04

问题已经回答了(顺便说一句,Ben 提供了非常好的和全面的答案),但为了完整性,我想添加另一个元素,这可能也非常方便。

在 Ben 建议的示例中:

<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>

以下ngOptions形式已被使用:select as label for value in array

标签是一个表达式,其结果将是<option>元素的标签在这种情况下,您可以执行某些字符串连接,以获得更复杂的选项标签。

例子:

  • ng-options="item.ID as item.Title + ' - ' + item.ID for item in items" 给你标签 Title - ID
  • ng-options="item.ID as item.Title + ' (' + item.Title.length + ')' for item in items"为您提供标签,例如Title (X)X标题字符串的长度在哪里

您还可以使用过滤器,例如,

  • ng-options="item.ID as item.Title + ' (' + (item.Title | uppercase) + ')' for item in items"为您提供类似的标签Title (TITLE),其中 Title 属性和 TITLE 的 Title 值是相同的值,但转换为大写字符。
  • ng-options="item.ID as item.Title + ' (' + (item.SomeDate | date) + ')' for item in items"给你标签Title (27 Sep 2015),如果你的模型有一个属性SomeDate

在 CoffeeScript 中:

#directive
app.directive('select2', ->
    templateUrl: 'partials/select.html'
    restrict: 'E'
    transclude: 1
    replace: 1
    scope:
        options: '='
        model: '='
    link: (scope, el, atr)->
        el.bind 'change', ->
            console.log this.value
            scope.model = parseInt(this.value)
            console.log scope
            scope.$apply()
)
<!-- HTML partial -->
<select>
  <option ng-repeat='o in options'
          value='{{$index}}' ng-bind='o'></option>
</select>

<!-- HTML usage -->
<select2 options='mnuOffline' model='offlinePage.toggle' ></select2>

<!-- Conclusion -->
<p>Sometimes it's much easier to create your own directive...</p>
不要忘记你radixparseInthttp : //davidwalsh.name/parseint-radix
2021-03-27 03:51:04