如何使用ng-options来selectng-class

我有一个Person对象的数组

var persons = [ {Name:'John',Eligible:true}, {Name:'Mark',Eligible:true}, {Name:'Sam',Eligible:false}, {Name:'Edward',Eligible:false}, {Name:'Michael',Eligible:true} ]; 

而我正在使用像这样的ng选项select:

 <select ng-model="Blah" ng-options="person.Name for person in persons"></select> 

我想用合格的 红色显示logging。 所以问题是我如何在select使用ng-class来实现这一目标? 由于我们不使用任何option标签,它不会工作,如果我只是在select元素本身添加ng-class

您可以创build一个指令,在处理ngOptions指令后处理选项,并使用相应的类更新它们。

更新 :旧的代码有一些错误,自从我回答这个问题,我学到了一点。 这是一个在1.2.2中重做的Plunk(但是也应该在1.0.X中工作)

这里更新了代码:

 app.directive('optionsClass', function ($parse) { return { require: 'select', link: function(scope, elem, attrs, ngSelect) { // get the source for the items array that populates the select. var optionsSourceStr = attrs.ngOptions.split(' ').pop(), // use $parse to get a function from the options-class attribute // that you can use to evaluate later. getOptionsClass = $parse(attrs.optionsClass); scope.$watch(optionsSourceStr, function(items) { // when the options source changes loop through its items. angular.forEach(items, function(item, index) { // evaluate against the item to get a mapping object for // for your classes. var classes = getOptionsClass(item), // also get the option you're going to need. This can be found // by looking for the option with the appropriate index in the // value attribute. option = elem.find('option[value=' + index + ']'); // now loop through the key/value pairs in the mapping object // and apply the classes that evaluated to be truthy. angular.forEach(classes, function(add, className) { if(add) { angular.element(option).addClass(className); } }); }); }); } }; }); 

以下是您如何在标记中使用它的方法:

 <select ng-model="foo" ng-options="x.name for x in items" options-class="{ 'is-eligible' : eligible, 'not-eligible': !eligible }"></select> 

它像ng-class一样工作,除了它在每个项目收集的基础上。

在这种情况下,只能在选项标签中使用ng-repeat时才能应用ng-class:

 <select ng-model="Blah"> <option ng-repeat="person in persons" ng-class="{red: person.Eligible}">{{person.Name}}</option> </select> 

这将给您的“合格”人员提供自定义的类,但是CSS不会在滚石上一致地工作。

Plunker 。

我想对接受的答案发表评论,但由于我没有足够的声望点,我必须添加一个答案。 我知道这是一个古老的问题,但最近添加到接受的答案的评论。

对于angularjs 1.4.x,build议的指令必须被修改以使其再次工作。 由于ngOptions的突破性变化,选项的值不再是索引,所以行

option = elem.find('option[value=' + index + ']');

将不再工作。

如果你改变了闯入者的代码

<select ng-model="foo" ng-options="x.id as x.name for x in items" options-class="{ 'is-eligible' : eligible, 'not-eligible': !eligible }"></select>

结果,选项标签的值现在是

value="number:x" (x是item对象的id)

将指令更改为

option = elem.find('option[value=\'number:' + item.id + '\']');

让它再次运作。

当然,这不是一个通用的解决scheme,因为如果你的对象中没有一个id,该怎么办? 然后你会在你的option标签中findvalue="object:y" ,其中y是由angularjs生成的数字,但是这个y不能映射到你的项目。

希望这可以帮助一些人在更新angularjs到1.4.x之后再次获得他们的代码

我也尝试在ng-options中使用该track by ,但没有得到它的工作。 也许有更多的经验,在angularjs然后我(=我的第一个项目在angularjs)?

该指令是一种方式,但我使用了一个自定义filter。 如果你知道如何select你的元素,你应该没问题。 挑战在于findselect中的当前选项元素。 我可以使用“包含”select器,但选项中的文本可能不是唯一的项目。 为了find价值的select,我注入了范围和项目本身。

 <select ng-model="foo" ng-options="item.name|addClass:{eligible:item.eligible,className:'eligible',scope:this,item:item} for item in items"></select> 

在js中:

 var app = angular.module('test', []); app.filter('addClass', function() { return function(text, opt) { var i; $.each(opt.scope.items,function(index,item) { if (item.id === opt.item.id) { i = index; return false; } }); var elem = angular.element("select > option[value='" + i + "']"); var classTail = opt.className; if (opt.eligible) { elem.addClass('is-' + classTail); elem.removeClass('not-' + classTail); } else { elem.addClass('not-' + classTail); elem.removeClass('is-' + classTail); } return text; } }) app.controller('MainCtrl', function($scope) { $scope.items = [ { name: 'foo',id: 'x1',eligible: true}, { name: 'bar',id: 'x2',eligible: false}, { name: 'test',id: 'x3',eligible: true} ]; }); 

在这里你可以看到它的工作 。

接受的答案不适合我,所以我find了一个没有自定义指令使用track by的替代方法:

 <select ng-model="foo" ng-options="x.name for x in items track by x.eligible"></select> 

每个选项现在获得值x.eligible。 在CSS中,你可以设置值为true的样式(我认为true必须是一个string)。 CSS:

 option[value="true"]{ color: red; } 

由于声誉的原因,我不能将其作为评论来写,但是我已经更新了可以接受的与Angular 1.4.8一起工作的答案。 感谢Ben Lesh的原始答案,这对我有很大的帮助。 差异似乎是更新的Angular生成这样的选项:

 <option class="is-eligible" label="foo" value="object:1">foo</option> 

所以代码

 option = elem.find('option[value=' + index + ']'); 

将无法find选项。 我的更改parsingngOptions并确定标签使用的项目的哪个字段,并find基于该值的选项而不是值。 看到:

http://plnkr.co/edit/MMZfuNZyouaNGulfJn41

我知道我晚了一些,但是对于那些想用纯CSS来解决这个问题的人来说,如果不使用指令,你可以像这样做一个css类:

  select.blueSelect option[value="false"]{ color:#01aac7; } 

这个CSS规则说:find所有的元素与值=假的标签名称“选项”内的每个“select”有一个类“blueSelect”,并使文本颜色#01aac7; (一片蓝色)

在你的情况下,你的HTML将如下所示:

  <select class="form-control blueSelect" name="persons" id="persons1" ng-options="person as person.name for person in $ctrl.persons track by person.Eligible" ng-model="$ctrl.selectedPerson" required> <option disabled selected value="">Default value</option> </select> 

ng-options中的轨迹是什么来跟踪选项,或者每个选项的“值”字段。 请注意,根据您的项目需要,您可能需要做一些调整,使其按照您的要求进行工作。

但是,如果有多个选项的“合格”字段具有相同的值,那么这不会起作用。 所以要做到这一点,我们创build一个复合expression式来跟踪,这样我们可以在每个选项中有独特的值跟踪。 在这种情况下,我们将Name和Eligible字段组合在一起

所以现在我们的html看起来像这样

 <select class="form-control blueSelect" name="persons" id="persons2" ng-options="person as person.name for person in $ctrl.persons track by (person.name + person.Eligible)" ng-model="$ctrl.selectedPerson" required> <option disabled selected value="">Default value</option> </select> 

和我们的CSS:

  select.blueSelect option[value*="False"]{ color:#01aac7; } 

请注意值旁边的*,这是一个正则expression式,意思是在选项元素的值字段中某处find单词“False”。

快速编辑您还可以select使用ng-optionsexpression式中的“disable when”禁用带有Eligible = False的选项,例如:

通过 trackexpr 禁用 数组 轨道中的 标签 禁用

我会留下如何在你的情况下使用它来找出;-)

这适用于简单的css修改,更复杂的东西,你可能需要一个指令或其他方法。 在铬testing。

我希望这可以帮助那里的人。 🙂

如果您不仅希望以红色显示它们,而且防止用户select选项,则可以disable when以下情况下使用disable when

 <select ng-model="Blah" ng-options="person.Name disable when !person.Eligible for person in persons"> </select> 

然后你可以使用CSS来设置禁用选项的颜色。