Почему бесконечная ошибка дайджеста при компиляции html-текста (из БД), который содержит директиву

  • У меня есть контроллер (скажем, SampleController), в котором он получает данные (в виде следующего html-текста) из службы $http и назначает их $scope.htmlText

    <p>This is some content text
         <span class='sampleClassDirective' pid='1'>P1 Value</span> 
         some other text 
         <span class='sampleClassDirective' pid='2'>P2 Value</span> 
    some more text </p>
    
  • Я хочу отобразить этот html-текст в представлении. Поскольку это html-текст, я могу использовать директиву ng-html-bind для отображения html-текста как есть.

  • но я хочу скомпилировать html-текст, чтобы директивы внутри html-текста могли получить свои шаблоны, если таковые имеются

  • Настоящая проблема начинается здесь

  • Как вы можете видеть выше, контент имеет несколько тегов с class="sampleClassDirective"
  • У меня есть директива с именем "sampleClassDirective"
  • Эта директива использует всплывающий компонент ui.bootstrap в своем шаблоне.

    angular.module('app').dirctive('sampleClassDirective', 
        function(){
           return {
               restrict:'C',
               transclude:true,
               template:'<span uib-popover="This is pid">'+
                           '<ng-transclude></ng-transclude>'+
                        '</span>'
           }
        });
    
  • Теперь я хочу скомпилировать весь htmlText, который я получил в sampleController, чтобы были скомпилированы «sampleClassDirective» и «uib-popover».

  • Итак, я дал

    <div id='htmlContent' ng-bind-html='render()'></div>
    
  • В SampleController

    $scope.render = function(){
        var elm = angular.element(htmlText);
        // compiling each directive
        var classDirectives = $(elm).find(".sampleClassDirective");
        for(var i=0, iMax=classDirectives.length; i<iMax; i++){
            $(elm).find(".sampleClassDirective")[i].append($compile(classDirectives[i])($scope));
        }
        // or can we compile all htmlText at once?
        // elm = $compile(elm)($scope)
    
        return $sce.trustAsHtml($(elm).html());
    }
    
  • **Вопрос : **

  • Пока он компилируется, почему я получаю $rootScope бесконечную ошибку $digest, и он прерывается?

person Siva Kumar    schedule 20.11.2015    source источник


Ответы (2)


Помещение выполняемой функции в директиву angular обычно приводит к циклу дайджеста. Я бы попробовал поместить вывод рендеринга в другую переменную и добавить ее в ng-bind html, например

$scope.renderedOutput = $scope.render();
<div id='htmlContent' ng-bind-html='renderedOutput'></div>
person Scott Schwalbe    schedule 20.11.2015
comment
Спасибо ... Это чисто и прямолинейно ... У вас есть какая-либо документация по этому поводу, я хотел узнать об этом больше. - person Siva Kumar; 23.11.2015
comment
Я только что понял это на собственном опыте, когда я поместил консольный журнал в функцию, и он печатает 200 раз. Я не совсем уверен, почему angular сходит с ума, когда вы выполняете функцию в html. Я бы просто погуглил цикл дайджестов, чтобы узнать больше. - person Scott Schwalbe; 23.11.2015
comment
Спасибо, это полезно - person Siva Kumar; 24.11.2015

Пока ты этого не делаешь

$('#htmlContent').html(htmlText)
$compile($('#htmlContent'))($scope)
person Qi Tang    schedule 20.11.2015
comment
Спасибо за ваш ответ. Позвольте мне попробовать, я скоро вернусь к этому - person Siva Kumar; 20.11.2015
comment
Это работает.. Спасибо, но в этом примере у меня есть только один '#htmlContent', но в моем реальном приложении у меня есть этот div внутри ng-repeat, поэтому к моменту его выполнения элемент html недоступен. Поэтому я заключил $timeout для нажатия на стек событий. Он рендерится, но не работает полностью. Кстати, спасибо, что дал мне отправную точку. Я проверю. - person Siva Kumar; 20.11.2015
comment
Тогда я думаю, вы можете создать директиву и поместить ее в свой ng-repeat. - person Qi Tang; 20.11.2015