我有以下指令在选择的开头设置10种最常用的语言并设置自定义css类:
app.directive('sortTopLocales', function ($timeout) {
// copied from angular-chosen (to get the array of ng-options)
var NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/;
var top10languages = ['en', 'zh', 'es', 'ja', 'pt', 'de', 'ar', 'fr', 'ru', 'ko'];
var top10languagesReversed = top10languages.reverse();
var cssClass = 'top10';
return {
restrict: 'A',
link: function(scope, element, attrs) {
if (attrs.ngOptions) {
var match = attrs.ngOptions.match(NG_OPTIONS_REGEXP);
scope.$watchCollection(match[7], function(locales) {
var alreadySorted = element.find('option.'+cssClass).length;
if(angular.isUndefined(locales) || alreadySorted) { return; }
var top10Index = 0;
$timeout(function() {
element.find('option.'+cssClass).removeClass(cssClass); // reset CSS class
angular.forEach(top10languagesReversed, function(locale) {
var index = locales.indexOf(locale);
if(index !== -1) {
locales.splice(index, 1); // removes it from the array
locales.unshift(locale); // sets it at the beginning of the array
var option = element.find('option[value=' + top10Index + ']');
option.addClass(cssClass);
top10Index++;
}
});
console.log(scope.$eval(match[7])[0], locales[0]);
// without filter => 'en', 'en'
// with filter => 'aa', 'en'
});
});
}
}
};
});
它可以按预期运行而不使用过滤器,但是当我在ng-options
中使用过滤器时,它不会:
工作:
ng-options="locale for locale in locales" // match[7] = 'locales'
不工作:
ng-options="locale for locale in locales | orderBy" // match[7] = 'locales | orderBy'
更改的数组和$ watchCollection的表达式有不同的输出。
scope.$eval(match[7])[0] // 'aa'
locales[0] // 'en'
当我在指令代码中使用过滤器而不是在HTML中时,数组也不会更新。
所以基本上我的问题是:如何在$ watchCollection中更新数组并使用过滤器更改以在ng-options中使用它?