我有一个Person对象数组
var persons = [
{Name:'John',Eligible:true},
{Name:'Mark',Eligible:true},
{Name:'Sam',Eligible:false},
{Name:'Edward',Eligible:false},
{Name:'Michael',Eligible:true}
];
我正在使用带有这样的ng-options的select:
<select ng-model="Blah" ng-options="person.Name for person in persons"></select>
我想以红色颜色显示符合条件:false 的记录。
所以问题是如何使用ng-class
中的select
来实现这一目标?由于我们没有使用任何option
代码,因此我只需在ng-class
元素中添加select
就无法使用。
答案 0 :(得分:33)
您可以创建一个指令,在处理ngOptions指令后处理这些选项,并使用适当的类更新它们。
更新:旧代码有一些错误,自从我回答这个问题以来,我学到了一些东西。 Here is a Plunk that was redone in 1.2.2 (but should work in 1.0.X as well)
以下已更新代码:
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类似,但除了它是基于每个项目的集合。
答案 1 :(得分:13)
在这种情况下,只有在ng-repeat
使用选项标记时才能应用ng-class:
<select ng-model="Blah">
<option ng-repeat="person in persons" ng-class="{red: person.Eligible}">{{person.Name}}</option>
</select>
这将为您的“合格”人员提供自定义课程,但CSS不会在不同的人之间保持一致。
答案 2 :(得分:4)
我想评论接受的答案,但由于我没有足够的声誉点,我必须添加一个答案。 我知道这是一个老问题,但是最近添加到已接受答案中的评论。
对于angularjs 1.4.x,必须调整建议的指令以使其再次工作。 由于ngOptions中的重大变化,选项的值不再是索引,因此行
option = elem.find('option[value=' + index + ']');
将不再有效。
如果您将plunker中的代码更改为
<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是项目对象的id)
将指令更改为
option = elem.find('option[value=\'number:' + item.id + '\']');
让它再次运作。
当然这不是一般的解决方案,因为如果你的对象中没有id怎么办?
然后,您会在选项标记中找到value="object:y"
,其中y是由angularjs生成的数字,但是使用此y
,您无法映射到您的商品。
希望这可以帮助一些人在将angularjs更新到1.4.x之后再次使用他们的代码
我还尝试在ng-options中使用track by
,但没有让它工作。
也许那些对angularjs有更多经验的人然后是我(=我在angularjs的第一个项目)?
答案 3 :(得分:3)
该指令是单向的,但我使用了自定义过滤器。 如果您知道如何选择元素,那么您应该没问题。挑战是在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}
];
});
您可see it work。
答案 4 :(得分:3)
接受的答案对我不起作用,所以我找到了一个没有使用track by
的自定义指令的替代方案:
<select ng-model="foo" ng-options="x.name for x in items track by x.eligible"></select>
现在每个选项都获得x.eligible值。在CSS中,您可以使用value = true设置样式选项(我认为true必须是字符串)。 CSS:
option[value="true"]{
color: red;
}
答案 5 :(得分:3)
如果您不仅希望以红色显示它们而阻止用户选择选项,您可以使用disable when
:
<select
ng-model="Blah"
ng-options="person.Name disable when !person.Eligible for person in persons">
</select>
然后,您可以使用CSS设置禁用选项的颜色。
答案 6 :(得分:2)
由于声誉,我不能将此作为评论写出来,但我已更新了使用Angular 1.4.8的已接受答案的plunker。感谢Ben Lesh的原始答案,它给了我很多帮助。差异似乎是较新的Angular会生成如下选项:
<option class="is-eligible" label="foo" value="object:1">foo</option>
所以代码
option = elem.find('option[value=' + index + ']');
无法找到该选项。我的更改解析ngOptions并确定项目的哪个字段用于标签,并根据该值而不是值查找选项。参见:
答案 7 :(得分:2)
我知道我参加派对有点晚了,但是对于想要用纯CSS解决这个问题的人来说,如果不使用指令,你可以像这样制作一个css类:
select.blueSelect option[value="false"]{
color:#01aac7;
}
此css规则说明:使用标记名称&#39;选项&#39;查找值为false的所有元素在每个人的内部选择&#39;有一个班级&#34; blueSelect&#34;并使文字颜色#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内部的轨道将保留跟踪选项的内容,或者&#34;值&#34;每个选项的字段。请注意,根据您的项目需求,您可能需要进行一些调整以使其按照您的要求工作。
但是,如果符合条件的字段具有相同值的多个选项,则无法正常工作。因此,为了使这项工作,我们创建一个复合表达式来跟踪,这样我们可以在每个选项中有唯一的值来跟踪。在这种情况下,我们将字段名称和合格
组合在一起所以现在我们的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;
}
注意值旁边的*,这是一个正则表达式,意思是找到单词&#34; False&#34;选项元素的值字段中的某个位置。
快速修改 您还可以选择使用&#34;禁用符合条件= False时禁用选项。在ng-options表达式中,例如:
标签 禁用 > > strong> 数组 跟踪 trackexpr
我将在你的案例中留下如何使用它来找出答案; - )
这适用于简单的CSS修改,对于更复杂的东西,您可能需要指令或其他方法。用铬测试。
我希望这可以帮助那些人。 : - )
答案 8 :(得分:-1)
我发现另一种解决方法比添加指令或过滤器更容易,这是为应用该样式的onfocus事件添加处理程序。
angular.element('select.styled').focus( function() {
angular.element(this).find('option').addClass('myStyle');
});