繁体   English   中英

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

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

我正在尝试编写将分数与颜色关联的指令。

我已经尝试过了,而Plunker在这里 指令本身在这里:

.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 
    }
}) 

我有几个问题。

  1. 首先,对我来说很明显,我应该在link函数中执行$watch 我正在创建一个无限的摘要循环,这不好。 不过,我仍然不确定为什么。
  2. 我没有正确地操作DOM。 即使我在调用$elem.removeClass() ,它也无法正常工作-该元素保留了以前拥有的所有类。

什么是正确的方法?

只是使事情正常的建议:

  1. 不需要同时$watch scoreptsPossible因为从相应的属性值加载值后,后者永远不会改变。 您还可以访问$watch回调函数中的scope变量。
  2. 这是不寻常的,因为我期望您的removeClass()能正常工作。 同时,您可以在这里尝试removeAttr('class')

这是带有建议更改的Plunker

您需要使用$watchCollection而不是$watch 您正在将数组传递给$watch ,这是$watchCollection期望的。

  1. 正如@miqid所说,无需同时监视score和ptsPossible,因为您只想在得分变化时做出反应(至少在这种情况下会出现)。

  2. 这里的问题是您正在使用jqLit​​e的removeClass函数而不是jQuery的 removeClass函数。 如果代码中没有在Angular之前包含jQuery,则Angular会改用jqLit​​e函数,这类似于较小,更简单的jQuery版本。 它也略有不同。 jQuery的removeClass() ,将删除所有没有传递参数的类。 jqLit​​e不会做相同的事情,只会删除您作为参数传递的那些类。

您根本没有包含jQuery,因此就是这种情况。 这是经过编辑的“ Plunker” 您可以检查jQuery现在是否包含在顶部,并且一切正常。 而且$ watch更简单。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM