AngularJS ngClass在ngRepeat中的自定义指令中的ngRepeat中不起作用

时间:2014-02-05 22:18:51

标签: angularjs angularjs-directive angularjs-ng-repeat ng-repeat ng-class

这是一个吸烟者:

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();
            });
        }
    }
});

1 个答案:

答案 0 :(得分:0)

对我来说第一件看起来很可疑的事情就是你重新分配了$ scope.dots属性和你的numActiveDots函数,这通常是以NaN结束的。该属性作为字符串传递给您的指令,然后您将其解析/重新分配为数字。我尝试将解析后的值重命名为$ scope.dotsinternal。这似乎使它成功。

http://plnkr.co/edit/STwuts2D169iBLDoTtE2?p=preview

改变这个:

$scope.dots = angular.isUndefined($scope.dots)?5:parseInt($scope.dots);

到此:

$scope.dotsinternal = angular.isUndefined($scope.dots)?5:parseInt($scope.dots);

然后将$ scope.dots的所有引用更新为$ scope.dotsinternal。