在指令中使用 $compile 会触发 AngularJS 无限摘要错误 [英] Using $compile in a directive triggers AngularJS infinite digest error

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

问题描述

有没有想过为什么这个指令会触发无限摘要错误?

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

它似乎是触发模型更新的 scope.$watch() 函数中的第一行,因为当我删除该行时,它不会触发错误.

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

我对为什么该行触发另一个 $digest 感到有点困惑 - 它似乎没有直接更新 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?)

推荐答案

当你使用 scope.$watch() 和一个函数而没有 watch 表达式时,它会注册一个被触发的观察者每个消化周期.由于您在该观察者中调用 $compile,因此每次都有效地触发另一个摘要循环,因为它需要处理由您的模板创建的观察者.这有效地创建了无限的消化周期.

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.

要使用相同的代码,您可能应该只在 postLink 函数中编译一次,但我认为您甚至不需要这样做 - 您应该可以只使用 template 属性.然后,您的 $watch() 语句应包含一个针对您要监视更改的属性的表达式 - 在这种情况下,只需 'message',并相应地更新 HTML.

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.

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

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