使用AngularJS的ng选项来处理select

我已经在其他文章中读过,但我无法弄清楚。

我有一个数组,

$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的选项。

我已阅读选择和尝试,但我无法弄清楚。

有一点需要注意的是ngModel是ngOptions工作所必需的…注意ng-model="blah"这是说“设置$ scope.blah到选定的值”。

尝试这个:

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

以下是AngularJS的文档(如果你还没有看到):

对于数组数据源:

  • 数组中的值的标签
  • 选择数组中的值作为标签
  • 在数组中按值分组标签=在数组中按值分组选择标签

对于对象数据源:

  • 对象中的(键,值)标签
  • 选择对象中的(键,值)作为标签
  • 对象中的(键,值)按组标记
  • 在对象中按(键,值)逐组选择作为标签

有关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来处理; 你应该只关心你范围内的模型。

这是一个展示上面的行为,并显示HTML写出来的笨蛋


处理默认选项:

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

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

你可以通过添加一个简单的ng-init来设置模型(从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> 

我正在学习AngularJS,并且正在为选择而苦苦挣扎。 我知道这个问题已经得到解答,但是我想分享一些更多的代码。

在我的测试中,我有两个列表框:汽车制造和汽车模型。 模型列表被禁用,直到选择一些make。 如果在生成列表框中的选择稍后重置(设置为“选择生成”),则模型列表框再次被禁用,并且其选择也被重置(到“选择模型”)。 当模型只是硬编码时,作为资源进行检索。

使JSON:

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

services.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> 

controllers.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"}; } 

由于某种原因,AngularJS允许我困惑。 他们的文档在这方面非常糟糕。 更好的变化的例子将是受欢迎的。

无论如何,本·莱斯的答案略有不同。

我的数据收集如下所示:

 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等)。

添加跟踪通过修复它为我:

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

这个问题已经得到了解答(顺便说一下,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例如Title - ID
  • ng-options="item.ID as item.Title + ' (' + item.Title.length + ')' for item in items"提供Title (X) ,如Title (X) ,其中X是标题字符串的长度。

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

  • ng-options="item.ID as item.Title + ' (' + (item.Title | uppercase) + ')' for item in items"提供Title (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> 

如果您需要每个选项的自定义标题,则ng-options不适用。 而是使用ng-repeat选项:

 <select ng-model="myVariable"> <option ng-repeat="item in items" value="{{item.ID}}" title="Custom title: {{item.Title}} [{{item.ID}}]"> {{item.Title}} </option> </select> 

我希望以下将为你工作。

 <select class="form-control" ng-model="selectedOption" ng-options="option.name + ' (' + (option.price | currency:'USD$') + ')' for option in options"> </select> 

这可能是有用的。 绑定不总是工作。

 <select id="product" class="form-control" name="product" required ng-model="issue.productId" ng-change="getProductVersions()" ng-options="p.id as p.shortName for p in products"></select> 

例如,您从REST服务填充选项列表源模型。 在填写清单之前已经知道选定的值,并且已经设定。 用$ http执行REST请求后,列表选项就完成了。

但是选择的选项没有设置。 由于未知的原因,AngularJS在shadow $ digest执行中没有绑定选择,因为它应该是。 我必须使用jQuery来设置选择。 这很重要! AngularJS在shadow中将前缀添加到由ng-repeat选项生成的attr“value”的值。 对于int它是“number:”。

 $scope.issue.productId = productId; function activate() { $http.get('/product/list') .then(function (response) { $scope.products = response.data; if (productId) { console.log("" + $("#product option").length);//for clarity $timeout(function () { console.log("" + $("#product option").length);//for clarity $('#product').val('number:'+productId); }, 200); } }); }