简体   繁体   English

在链接内部使用手表会导致无限的摘要周期。

[英]Using a watch inside a link is causing an infinite digest cycle.

I'm trying to write a directive that associates a score with a color. 我正在尝试编写将分数与颜色关联的指令。

I've made an attempt already, and the Plunker is here . 我已经尝试过了,而Plunker在这里 The directive itself is here: 指令本身在这里:

.directive('scorebox', function () {
    function link ($scope, $elem, $attr) {
        var one = 1;
        $scope.$watch('[score,ptsPossible]', function (newValue) {
            pctScore = newValue[0] / newValue[1]
            if (pctScore <= 0.4) {
                rating = 'low';
            } else if (pctScore <= 0.6) {
                rating = 'med';
            } else if (pctScore <= 0.8) {
                rating = 'high';
            } else if (pctScore == 1) {
                rating = 'perfect';
            }

            $elem.removeClass();
            $elem.addClass('scorebox');
            $elem.addClass(rating);
            $elem.text(newValue[0] + "/" + newValue[1]);
        });
    };

    return {
        restrict: 'E',
        scope: {
            score: "=",
            ptsPossible: "="
        },
        link:link 
    }
}) 

I've got a couple of problems. 我有几个问题。

  1. First, it's pretty obvious to me that I'm not supposed to do a $watch inside a link function. 首先,对我来说很明显,我应该在link函数中执行$watch I'm creating an infinite digest cycle, and that's not good. 我正在创建一个无限的摘要循环,这不好。 I'm still not sure why, though. 不过,我仍然不确定为什么。
  2. I'm not manipulating the DOM correctly. 我没有正确地操作DOM。 Even though I'm calling $elem.removeClass() , it's not working--the element retains any classes it had before. 即使我在调用$elem.removeClass() ,它也无法正常工作-该元素保留了以前拥有的所有类。

What is the right way to do this? 什么是正确的方法?

Just a suggestion to get things working: 只是使事情正常的建议:

  1. There's no need to $watch both score and ptsPossible since the latter never changes after the value is loaded from its corresponding attribute value. 不需要同时$watch scoreptsPossible因为从相应的属性值加载值后,后者永远不会改变。 You also have access to scope variables inside the $watch callback function. 您还可以访问$watch回调函数中的scope变量。
  2. That's unusual as I would've expected your removeClass() to work as well. 这是不寻常的,因为我期望您的removeClass()能正常工作。 You could instead try removeAttr('class') here in the meanwhile. 同时,您可以在这里尝试removeAttr('class')

Here's a Plunker with the suggested changes. 这是带有建议更改的Plunker

You need to use $watchCollection and not $watch . 您需要使用$watchCollection而不是$watch You are passing in an array to $watch which is how $watchCollection expects. 您正在将数组传递给$watch ,这是$watchCollection期望的。

  1. As @miqid said, no need to $watch both score and ptsPossible, since you only want to react when score changes (at least in this situation you are presenting). 正如@miqid所说,无需同时监视score和ptsPossible,因为您只想在得分变化时做出反应(至少在这种情况下会出现)。

  2. The problem here, is you are using jqLite's removeClass function instead of jQuery's . 这里的问题是您正在使用jqLit​​e的removeClass函数而不是jQuery的 removeClass函数。 If jQuery is not included before Angular in the code, Angular will instead use jqLite functions, which is like a smaller, much simpler version of jQuery. 如果代码中没有在Angular之前包含jQuery,则Angular会改用jqLit​​e函数,这类似于较小,更简单的jQuery版本。 It is also, slightly different. 它也略有不同。 jQuery's removeClass() , will remove all classes is no parameter is passed. jQuery的removeClass() ,将删除所有没有传递参数的类。 jqLite will not do the same, it will just remove those classes that you pass as parameter. jqLit​​e不会做相同的事情,只会删除您作为参数传递的那些类。

You never included jQuery at all, so that's what's happening. 您根本没有包含jQuery,因此就是这种情况。 Here is the edited Plunker . 这是经过编辑的“ Plunker” You can check jQuery is now included in the top, and everything works as expected. 您可以检查jQuery现在是否包含在顶部,并且一切正常。 And also the $watch is much simpler. 而且$ watch更简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在绑定到内部带有$ http的函数时运行到无限的摘要周期 - Running into infinite digest cycle while binding to function that has $http inside 与ng-repeat一起使用功能会导致无限摘要循环 - Using function with ng-repeat causing infinite digest loop 如何在Angular中禁止监视语句或摘要循环 - How to suppress a watch statement or digest cycle in Angular 强制AngularJS指令在摘要周期外链接 - Forcing AngularJS directive to link outside digest cycle Angular是否会在相同的$ digest循环中重新评估相同的$ watch表达式? - Will Angular reevaluate identical $watch expressions in the same $digest cycle? 如何清空以下数组而又不会在Vue手表内部造成无限外观? - How to empty the following array without causing in infinite look inside this Vue watch? AngularJS [无限摘要周期]中无限嵌套注释的渲染视图 - Rendering view for infinitely nested comments in AngularJS [infinite digest cycle] 调试Angular的摘要周期:如何找到无限循环的原因? - Debugging Angular's digest cycle: How to find the cause of an infinite loop? 任何调用$ q通知的方式都不会导致$ digest循环吗? - Any way to call $q notify without causing $digest cycle? 如何使用PhantomJS启动Angular摘要循环? - How to start an Angular digest cycle using PhantomJS?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM