2015-10-09 1 views
1

Эй Я пытаюсь написать директиву для расширения ngOptions. Я довольно новичок в угловатости, поэтому, если вы видите все, что может быть улучшено, дайте мне знать.Расширение ngOptions

Итак, я хочу написать директиву, которая позволит мне добавлять атрибуты к параметрам, генерируемым ngOption. Я создал простую директиву, которая добавит заголовок, класс или любой атрибут, который я определяю для параметров. Это работает, но я чувствую, что это немного грязно. Имейте в виду, что не вся обработка ошибок присутствует. Это еще прототип.

Вот моя директива

.directive('ngOptionsExt', function($parse) { 
    //Simplified ng-options regex still messy 
    var regex = /^\s*([\s\S]+?)?\sfor\s+([\$\w][\$\w]*)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))$/; 
    return { 
    require: 'select', 
    link: function(scope, elem, attrs) { 

     var match = attrs.ngOptionsExt.match(regex); 

     if (match) { 
     var map = match[1], 
      option = match[2], 
      optionSource = match[3], 
      track = match[4] || false, 
      getOptionsAttrs = $parse(map); 

     scope.$watchCollection(optionSource, function(items) { 

      angular.forEach(items, function(item, index) { 
      var attributes = getOptionsAttrs(item); 

      if (track) 
       option = elem.find('option[' + track + '="' + item[track] + '"]'); 
      else 
       option = elem.find('option[value' + index + ']'); 

      angular.forEach(attributes, function(val, attrName) { 
       angular.element(option).attr(attrName, val); 
      }); 

      }); 
     }); 
     } 
    } 
    }; 
}); 

Использование:

ng-options-ext="{title: label, class: label} for option in options track by label" 

Где options такая же модель используется для ngOptions. Трек by просто используется для поиска опций по метке (не уверен, что это правильный путь), чтобы избежать использования индекса для добавления атрибутов.

Указанная выше директива добавит название и класс, который будет иметь такое же значение, как и метка элемента option.

Ребята, когда-либо приходилось писать что-то подобное и иметь какие-либо идеи о том, как улучшить это?

Благодаря

+1

Не могли бы вы написать независимую директиву, которая просто находит элементы «option» и добавляет нужные вам атрибуты и значения? – o4ohel

ответ

0

Вы можете использовать ngRepeat на <option> внутри <select>.

<select ng-model="value" ng-change="change()"> 
    <option ng-repeat="element in elements " value="{{element.value}}" 
     data-custom-attribute="...">{{element.value}}</option> 
</select> 
+0

Это не то же самое, что и ng-options – o4ohel

+0

Да, но это проще, чем создать другую директиву расширения ngOptions, и он также может обернуть этот html в другую директиву и заменить его для повторного использования ... –

+0

Один из Преимущества ngOptions в том, что он позволяет вам выбирать объект, но отображать ярлык ... очень полезно. – o4ohel

0

Эй, я закончил с чем-то вроде этого. Кажется хорошо работает и выглядит чище, чем у меня раньше. @ o4ohel, я пошел вперед и просто зациклился на таких вариантах, как вы упомянули. Затем отобразили атрибуты источника опций.

.directive('ngOptionsAttr', function ($parse) { 
    return { 
     require: 'select', 
     link: function(scope, elem, attrs) { 
      var match = attrs.ngOptionsAttr.split(' for '), 
       map = match[0], 
       src = match[1], 
       getOptionsAttrs = $parse(map); 
      scope.$watchCollection(src, function() { 
       angular.forEach(elem.find("option"), function (option) { 
        angular.forEach(getOptionsAttrs(option), function(val, name) { 
         angular.element(option).attr(name, val); 
        }); 
       }); 
      }); 
     } 
    }; 
}); 

Использование:

ng-options-attr="{title: label} for options" 
0

У меня была аналогичная проблема, и решить ее только переопределяя $ делают функцию и используется lodash для контура через параметры, чтобы установить свои атрибуты,

link: function(scope, element, attributes, modelCtrl){ 
    modelCtrl.$render = function() { 
     var select = element.find(select); 
     _.each(select.children(), function(option) { 
      //set attributes here 
     } 
    } 
} 

Единственное требование здесь - потребовать: «ngModel» в определении вашей директивы.