Как я могу получить свой скомпилированный массив из ng-options в пользовательской директиве?
У меня есть специальная директива, которую я украшаю <select ng-options="">
с таким...
<select custom ng-model="selected" ng-options="o for o in values">
с custom
как моя директива и values
будучи простым массивом. Вот моя реализация...
<select custom ng-model="selected" ng-options="o for o in values">
<option value selected>uhh?</option>
</select>
app.directive('custom', [function() {
return {
scope: {},
link: function(scope, elem, attrs) {
// how can I get my array of values here?
}
}
}])
app.controller('ctrl', ['$scope', function($scope) {
$scope.values = ['er', 'um', 'eh'];
}])
В моем link
Я вижу это как таковой
console.log(attrs.ngOptions);
Который, в этом случае, выходит из буквального "o for o in values"
, Могу ли я как-то разобрать или скомпилировать это в моем link
получить массив? Я вижу, что могу взять это, если я сделаю что-то вроде scope.$parent.values
, но это кажется ненужным, и мне нужно знать имя "values"
, Я могу, вероятно, получить его с помощью каких-то хакерских манипуляций со струнами, чтобы нацелиться на него, но я надеюсь, что есть более интуитивный способ.
хакер например
var array = attrs.ngOptions.split(' ').pop(); // "values"
console.log(scope.$parent[array]);
Дополнительное примечание - ограничено AngularJS 1.2.x для этого примера
JSFiddle Link - пример
2 ответа
Начиная с Angular v1.4, ни select
ни ngOptions
директивы предоставляют API для получения массива элементов, который приводит к <option>
с, так что нам остается только 2 варианта - 1) пройти values
массив явно custom
директива как значение атрибута, или 2) получить его из микросинтаксиса ng-options
,
С № 1 - подход прост.
С # 2 - нам нужно проанализировать микросинтаксис, например с RegExp
, Это хрупко, так как микросинтаксис может измениться в будущем.
Мы могли бы использовать собственное выражение регулярного выражения Angular (см. Src v1.4.3), чтобы проанализировать этот синтаксис:
var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?(?:\s+disable\s+when\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]+?))?$/;
(восьмая группа соответствует пунктам)
Или мы могли бы сделать это более простым регулярным выражением, возможно, даже более стабильным, например:
/^.*\s+in\s+(\S+)[\s\S]*$/
Во всяком случае, директива будет выглядеть так:
app.directive('custom', function($parse) {
return {
scope: {},
link: function(scope, elem, attrs) {
var optionsExp = attrs.ngOptions;
var match = optionsExp.match(NG_OPTIONS_REGEXP);
var valuesExp = match[8];
var valuesFn = $parse(valuesExp);
var values = valuesFn(scope.$parent);
// or simpler:
// var values = $parse(match[8])(scope.$parent);
}
}
})
Смотри скрипку ниже. JsFiddle
<div ng-app="app" ng-controller="ctrl">
<select custom ng-model="selected" ng-options="o for o in values">
<option value selected>uhh?</option>
</select>
</div>
var app = angular.module('app', []);
app.directive('custom', [function(){
return {
link: function(scope, elem, attrs) {
console.log(scope.values)
}
}
}])
app.controller('ctrl', ['$scope', function($scope){
$scope.values = ['er', 'um', 'eh'];
}])