如何从自定义指令中的 ng-options 获取编译后的数组?
How can I get my compiled array from ng-options in a custom directive?
我有一个自定义指令,我正在用它来装饰 <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]);
旁注 - 在本例中限制为 AngularJS1.2.x
JSFiddle Link - 例子
看下面的fiddle。
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'];
}])
从 Angular v1.4 开始,select
和 ngOptions
指令均未提供 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);
}
}
})
我有一个自定义指令,我正在用它来装饰 <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]);
旁注 - 在本例中限制为 AngularJS1.2.x
JSFiddle Link - 例子
看下面的fiddle。 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'];
}])
从 Angular v1.4 开始,select
和 ngOptions
指令均未提供 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);
}
}
})