If you only need to bind the select to string values (not object), you can easily achieve what you want by using ngRepeat
ed <option>
elements (instead of ngOptions
):
<select ng-model="color">
<option value="">--- Select a color ---</option>
<option value="{{ c }}" style="background-color:{{ c }}" ng-repeat="c in colors">
{{ c }}
</option>
</select>
If you are in for a little custom directive, you can implement it like this:
app.directive('optionClassExpr', function ($compile, $parse) {
const NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;
return {
restrict: 'A',
link: function optionClassExprPostLink(scope, elem, attrs) {
const optionsExp = attrs.ngOptions;
if (!optionsExp) return;
const match = optionsExp.match(NG_OPTIONS_REGEXP);
if (!match) return;
const values = match[7];
const classExpr = $parse(attrs.optionClassExpr);
scope.$watchCollection(() => elem.children(), newValue => {
angular.forEach(newValue, child => {
const child = angular.element(child);
const val = child.val();
if (val) {
child.attr('ng-class', `${values}[${val}].${attrs.optionClassExpr}`);
$compile(child)(scope);
}
});
});
}
};
});
And use it like this:
<select
ng-model="someObj"
ng-options="obj as obj.color for obj in objects"
option-class-expr="color">
</select>
See, also, this updated short demo.