使用$编译指令触发AngularJS无限消化错误 [英] Using $compile in a directive triggers AngularJS infinite digest error

查看:113
本文介绍了使用$编译指令触发AngularJS无限消化错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是为什么这个指令触发无限消化错误有什么想法?

http://jsfiddle.net/smithkl42/cwrgLd0L/13/

  VAR应用= angular.module('prettifyTest',[]);
App.controller('myCtrl',函数($范围){
    $ scope.message =你好,世界!;
})App.directive('prettify',['$编译,函数($编译){
    VAR模板;
    返回{
        限制:'E',
        链接:功能(范围,元素,ATTRS){
            如果(!模板){
                模板= element.html();
            }
            范围。$表(函数(){
                VAR编译= $编译(模板)(范围);
                element.html('');
                element.append(编译);
                变种的html = element.html();
                VAR prettified = prettyPrintOne(HTML);
                element.html(prettified);
            });
        }
    };
}]);

这似乎是在范围。$腕表()的第一行的触发模型更新,当我删除了这一行函数,它不触发错误。

  VAR编译= $编译(模板)(范围);

我,为什么该线路将被触发另一个$消化有点困惑 - 它似乎并没有直接在范围更新任何东西。

有没有更好的方式来完成我想要做的,例如,一些其他的方式来检查,看看是否在范围内的键值实际上已经改变了,所以我可以重新编译模板? (而且是有抓住模板的更好的办法?)


解决方案

当您使用范围。$表()只是一个功能,并没有手表前pression,它注册,获取每个周期消化引发的守望。既然你叫 $编译的守望中,这是有效的,每次触发另一摘要周期,因为它需要处理你的模板创建的观察家。这将有效地创建您的无限摘要周期。

要使用相同的code,你应该只在你postLink功能编译一次,但我不认为你甚至需要做的 - 你应该能够只使用模板属性。那么你的 $腕表()语句应该包括一个前pression瞄准你想要观看更改​​属性 - 在这种情况下,只需消息,并相应更新HTML。

Any thoughts on why this directive is triggering an infinite digest error?

http://jsfiddle.net/smithkl42/cwrgLd0L/13/

var App = angular.module('prettifyTest', []);
App.controller('myCtrl', function ($scope) {
    $scope.message = 'Hello, world!';
})

App.directive('prettify', ['$compile', function ($compile) {
    var template;
    return {
        restrict: 'E',
        link: function (scope, element, attrs) {
            if (!template) {
                template = element.html();
            }
            scope.$watch(function () {
                var compiled = $compile(template)(scope);
                element.html('');
                element.append(compiled);
                var html = element.html();
                var prettified = prettyPrintOne(html);
                element.html(prettified);
            });
        }
    };
}]);

It seems to be the very first line in the scope.$watch() function that's triggering the model update, as when I remove that line, it doesn't trigger the error.

var compiled = $compile(template)(scope);

I'm a little confused as to why that line is triggering another $digest - it doesn't seem to be updating anything directly in the scope.

Is there a better way to accomplish what I'm trying to do, e.g., some other way to check to see if the key values in the scope have actually changed so I can recompile the template? (And is there a better way of grabbing the template?)

解决方案

When you use scope.$watch() with just a function and no watch expression, it registers a watcher that gets triggered on every digest cycle. Since you're calling $compile within that watcher, that's effectively triggering another digest cycle each time since it needs to process the watchers created by your template. This effectively creates your infinite digest cycle.

To use the same code, you should probably just be compiling once in your postLink function, but I don't think you even need to do that - you should be able just use the template property. Then your $watch() statement should include an expression targeting the property you want to watch for changes - in this case, just 'message', and update the HTML accordingly.

这篇关于使用$编译指令触发AngularJS无限消化错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆