I currently have the following directive on my select
.
ng-options="option.value as option.title for option in exportTypes"
$scope.exportTypes = an array of objects each with title
, value
, and generatesFile
attributes. I'd like the generatesFile
attribute to be added as a data-generates-file
attribute on each <option>
that is generated for this select.
Any thoughts on how to do this?
Maybe someone will correct me but I'm pretty sure you won't get this kind of control out of ng-options
. Angular manages the select behind the scenes for you when you use this, which is nice 90% of the time but can be limiting in situations like yours. I'm not sure what benchmarks you're looking at but I'd be willing to bet an ng-repeat
on the option elements is comparable in performance to using ng-options
.
I'd go with something like this:
<select ng-model="selectedExportType">
<option ng-repeat="exportType in exportTypes" data-generates-file="{{exportType.generatesFile}}" value="{{exportType.value}}">
{{exportType.title}}
</option>
</select>
Of course, this assumes you really do need that attribute on there. If all you need is access to that attribute on select then this is where ng-options
shines. Simply remove the option.value as
bit from your select and then you get the whole object back from your array when you make a selection.
http://plnkr.co/edit/6XPaficTbbzozSQqo6uE?p=preview
You can see in that demo that the selected item is the whole object, complete with someAttr
property which was never used in the select at all. If you inspect the DOM you won't see it. Angular tracks all this behind the scenes.
Here is a directive which can be used to add custom attributes when using ng-options
with <select>
, so you can prevent using ng-repeat
.directive('optionsCustomAttr', function ($parse) {
return {
priority: 0,
require: 'ngModel',
link: function (scope, iElement, iAttrs) {
scope.addCustomAttr = function (attr, element, data, fnDisableIfTrue) {
$("option", element).each(function (i, e) {
var locals = {};
locals[attr] = data[i];
$(e).attr(iAttrs.customAttrName ? iAttrs.customAttrName : 'custom-attr', fnDisableIfTrue(scope, locals));
});
};
var expElements = iAttrs['optionsCustomAttr'].match(/(.+)\s+for\s+(.+)\s+in\s+(.+)/);
var attrToWatch = expElements[3];
var fnDisableIfTrue = $parse(expElements[1]);
scope.$watch(attrToWatch, function (newValue) {
if (newValue)
scope.addCustomAttr(expElements[2], iElement, newValue, fnDisableIfTrue);
});
}
};
})
And then in your select,
<select ng-model="selectedExportType" ng-options="option.value as option.title for option in exportTypes"
options-custom-attr="option.generatesFile for option in exportTypes"
custom-attr-name="data-generates-file">
</select>
Note: This is a modified version of optionsDisabled
directory mentioned here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With