使用angularjs的ng-options处理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的选项。

我已经读了select并尝试了,但我不能解决它。

458359 次浏览

需要注意的一点是,ngModel是要求,以便ngOptions工作…注意ng-model="blah"表示“set $scope.”废话到选定的值”。

试试这个:

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

下面是AngularJS文档中的更多内容(如果你还没看过的话):

对于数组数据源:

  • 数组中值的标签
  • 为数组中的值选择标签
  • 为数组中的值按组标记组 = select as label group by group for数组中的值

对于对象数据源:

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

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

当你使用ng-optionsng-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来处理;您应该只关心作用域内模型中的内容。

< a href = " http://plnkr.co/edit/SxIvt4KThWLtWvh3PnOh?p=preview" rel="noreferrer">这是一个柱塞演示上面的行为,并显示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恰好被正确地初始化为一些“假”的东西,这可能会有点疯狂。在这种情况下,你很可能想在你的控制器中处理foo的初始化。

自定义默认选项:

这有点不同;在这里,你所需要做的就是添加一个option标签作为你的select的子标签,带有一个空的value属性,然后自定义它的内部文本:

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

注意:在这种情况下,即使您选择了不同的选项,“empty”选项也会保留在那里。在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被选中。如果在制作列表框中的选择稍后被重置(设置为“选择制作”),那么模型列表框再次被禁用,其选择也被重置(为“选择模型”)。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"};
}

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>

由于某些原因,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了,但是你需要在你的option标签上使用ng-repeat:

<select name="test">
<option ng-repeat="item in items" value="\{\{item.key}}">\{\{item.value}}</option>
</select>

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

在本建议的例子中:

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

使用了下面的ngOptions形式:

标签是一个表达式,其结果将是<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值是相同的值,但转换为大写字符。
  • 如果你的模型有一个属性SomeDateng-options="item.ID as item.Title + ' (' + (item.SomeDate | date) + ')' for item in items"会给你像Title (27 Sep 2015)这样的标签

如果每个选项都需要自定义标题,则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 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);
}
});
}