更新指令内的范围并防止错误:[$ rootScope:inprog]

时间:2014-10-11 15:50:36

标签: javascript angularjs timeout angularjs-scope directive

我正在尝试更改指令中的范围数据,我正在收到错误:[$ rootScope:inprog] $ digest已在进行中。 我尝试使用$ timeout但它没有帮助。 我正在遍历类别数组并显示面包屑(例如,something1> something2> something3> something4),它们在category.name中包含为字符串。

<div ng-repeat="category in categories">
       <div breadcrumbs="breadcrumbs" category="category">
        <span class="description" id="name_{{category.id}}" >{{category.name}}</span>
       <div>
</div>

我希望当这个div的容器缩小时,面包屑响应地变成这种形式'something1&gt; ...&gt; something3&gt; something4'或者'something1&gt; ...&gt; something4'取决于容器的宽度和面包屑的长度。

为了实现这一点,我创建了一个名为'breadcrumbs'的指令,它检查相关元素的大小是否大于20,这意味着必须缩小面包屑。 这是指令..

angular.module('demo')
.directive('breadcrumbs', [ '$log', '$window', function($log, $window) {
    'use strict';

    return {
        restrict: 'A',
        link: function( scope, elem, attrs ){
                scope.getElemHeight = function() {
                    return elem.height();
                }

                scope.shortenBreadcrumb  = function(){
                    if (scope.getElemHeight() > 20){  
                        console.log(scope.getElemHeight());
                         var breadcrumbArry = scope.category.name.split(" > ");
                         var i = 1;
                 //remove breadcrumb by breadcrumb until whole breadcrumbs string fits the container
                 while ((scope.getElemHeight() > 20) && (breadcrumbArry.length > 3)){
                            if (i == 1) breadcrumbArry[i] = "..."
                            else breadcrumbArry.splice(2, 1); // remove 1 element on index 2
                            scope.category.name = breadcrumbArry.join(" > ");
                            i++;
                            scope.$apply();
                 }
                    }

                }

                // Set on load
                scope.$watch(scope.getElemHeight, function (newValue, oldValue) {
                    scope.shortenBreadcrumb();
                    console.log("LOOOOOOAD "+scope.category.id);
                }, true);

                // Set on resize
                angular.element($window).bind('resize', function () {
                    scope.category.name = scope.category.fullBreadcrumb;
                    scope.shortenBreadcrumb();
                    scope.$apply();

                });                 
        },  
        scope: {
            category: '='
        }
    }
}]);

它在加载和窗口调整大小时运行良好,但我在控制台上不断提到错误。我在循环中尝试了$ timeout但是我然后我的浏览器崩溃了,因为它永远等待并且永远不会进入超时功能,因为它是从$ scope.watch调用的。 我真的需要帮助,因为我没有想法如何解决它。

以下是工作示例http://jsfiddle.net/radiolaria/0btwgmzj/29/如果您检查控制台输出,您将看到错误。

1 个答案:

答案 0 :(得分:0)

删除$scope.$apply两次调用,并用scope.$evalAsync(scope.shortenBreadcrumb);

替换对short-bread-crumb的调用