smiady smiady - 10 months ago 90
AngularJS Question

Angular not correctly compile ng-options

I want directive which replace tag range=[-3, 3] to ng-options.

Unfortunately below solution is not good

<html lang="pl">
<title>Its directive range</title>
<div ng-app="app">
<div ng-controller="AppCtrl">
<select ng-model="value" range="[-3, 3]"></select>

<script type="text/javascript" src=""></script>
<script type="text/javascript">
angular.module('directives', []);

angular.module('app', ['directives']);

angular.module('app').controller('AppCtrl', function($scope) {
$scope.value = 2;

angular.module('directives').directive('range', function($compile) {
return {
restrict: 'A',
scope: {
range: '='
link: function(scope, elem, attr) {
scope.options = [];

for(var i = scope.range[0]; i <= scope.range[1]; ++i) {

elem.attr('ng-options', 'o as o for o in options track by o');



After created ng-options tag select contain option value="number:2" instead of selected value 2 ...

Answer Source

ng-options directive makes possible selecting different types of variables, it can select mixed types like:

<select name="mydata" 
        ng-options="value.a || value for value in ['-10', -5, 0, 5,'10',{a: '20'},'25']">

where first, fifth and last items are STRINGs, one item before the last is OBJECT and the rest of items are NUMBERs. In HTML these options are rendered like:

<select name="mydata" 
        ng-model="number" ng-options="value.a || value for value in ['-10', -5, 0, 5,'10',{a: '20'},'25']">
  <option label="-10" value="string:-10">-10</option>
  <option label="-5" value="number:-5">-5</option>
  <option label="0" value="number:0">0</option>
  <option label="5" value="number:5">5</option>
  <option label="10" value="string:10" selected="selected">10</option>      
  <option label="20" value="object:8">20</option>
  <option label="25" value="string:25">25</option>

to distinct between types, the type itself with semicolons is added before the value, like number:5 or object:4, these type prefixes are ignored by ng-model which is updated properly, see plunker

I changed your range of numbers to range of strings, to make it similar to native HTML select element:

for (var i = scope.range[0]; i <= scope.range[1]; i++) {

type prefixes are omitted in this case, only on initial load there is <option value="? string:2 ?"></option> element, which is removed after first manual selection.