这是一个笨蛋:
http://plnkr.co/edit/hJsZFCBZhFT5rRo1lgSZ?p=preview
这是一个简单的指令,应该显示给定数量的点,并根据给定的值、最小值和最大值突出显示它们的子集,类似于星级。它单独工作时效果很好(正如您在 plunkr 的最后一行中看到的那样),但在 ngRepeat 中却不行。问题是指令自己的 ngRepeat 上的 ngClass 似乎失败了,即使 ngClass 中使用的表达式似乎在 ngClass 之外正确评估。在过去的几个小时里,我一直在为此扯头发,我就是想不通。
这是实际的代码:
HTML:
<div ng-repeat="row in [1,2,3,4,5]">
<match-dots value="{{ $index+1 }}" min="0" max="10">{{ isDotActive($index) }}</match-dots>
</div>
JS:
angular.module('app', [])
.directive('matchDots', function() {
return {
restrict: 'EA',
replace: true,
transclude: true,
template:
"<span class='match-dots-group'>" +
"<span class='match-dots-dot' ng-repeat='dot in dotsList()' ng-class='{ active: isDotActive($index) }' ng-transclude></span>" +
"</span>",
scope: {
dots: '@',
min: '@',
max: '@',
value: '@'
},
link: function(scope, elem) {
// save the previous class applied so we can remove it when the class changes
var previousClass = '';
/**
* set the class for the dots-group based on how many dots are active (n-active)
*/
scope.setDotsClass = function() {
if(previousClass != '') {
elem.removeClass(previousClass);
}
previousClass = "active-"+scope.numActiveDots();
elem.addClass(previousClass);
}
},
controller: function($scope) {
$scope.dots = angular.isUndefined($scope.dots)?5:parseInt($scope.dots);
$scope.min = angular.isUndefined($scope.min)?0:parseInt($scope.min);
$scope.max = angular.isUndefined($scope.max)?100:parseInt($scope.max);
/**
* create a list of numbers
* @returns {Array}
*/
$scope.dotsList = function() {
var arr = [];
for(var i=1; i<=$scope.dots; i++) {
arr.push(i);
}
return arr;
};
/**
* should the given dot be lit up?
* @param {number} dot
* @returns {boolean}
*/
$scope.isDotActive = function(dot) {
return dot < $scope.numActiveDots();
};
/**
* How many dots are active?
* @returns {number}
*/
$scope.numActiveDots = function() {
var activeDots = Math.ceil(($scope.value-$scope.min) / (($scope.max-$scope.min) / $scope.dots));
return isNaN(activeDots)?0:activeDots;
};
// make sure the value is an number
$scope.$watch('value', function(newValue) {
$scope.value = parseFloat(newValue);
$scope.setDotsClass();
});
// make sure the number of dots is actually a positive integer
$scope.$watch('dots', function(newDots) {
if(angular.isUndefined(newDots) || !newDots || newDots < 1) {
$scope.dots = 5;
} else {
$scope.dots = parseInt(newDots);
}
$scope.setDotsClass();
});
// make sure the min is not greater than the max
$scope.$watch('max', function(newMax) {
if(angular.isUndefined(newMax)) {
$scope.max = newMax = 100;
}
if(angular.isString(newMax)) {
$scope.max = parseFloat(newMax);
} else if(newMax < $scope.min) {
$scope.max = $scope.min;
$scope.min = newMax;
}
$scope.setDotsClass();
});
// make sure the max is not less than the min
$scope.$watch('min', function(newMin) {
if(angular.isUndefined(newMin)) {
$scope.min = newMin = 0;
}
if(angular.isString(newMin)) {
$scope.min = parseFloat(newMin);
} else if(newMin > $scope.max) {
$scope.min = $scope.max;
$scope.max = newMin;
}
$scope.setDotsClass();
});
}
}
});