如何从自定义指令中的ng-options中获取已编译的数组?

时间:2015-08-14 16:14:53

标签: javascript html angularjs angularjs-directive angularjs-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"的名字。我可以通过一些hacky感觉字符串操作来定位它,但我希望有一种更直观的方式。

hacky例如。

var array = attrs.ngOptions.split(' ').pop(); // "values"

console.log(scope.$parent[array]);

附注 - 对于此示例而言,收缩于AngularJS 1.2.x

JSFiddle Link - 示例

2 个答案:

答案 0 :(得分:9)

从Angular v1.4开始,selectngOptions指令都没有提供API来获取导致<option> s的项目数组,所以我们只留下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]+?))?$/;

(第8组匹配项目)

或者,我们可以使它成为一个更简单的正则表达式,甚至更稳定,例如:

/^.*\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);
    }
  }
})

答案 1 :(得分:-1)

看下面的小提琴。 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'];
}])