从后端渲染($ compile)html而不阻塞dom

时间:2016-11-24 19:46:30

标签: javascript html angularjs dom compilation

CONTEXT

我需要在我的AngularJS( v1.4 )应用中加载从后端获取的一些HTML并将其(html)插入到我的 partial (已加载)。部分已经加载了一些HTML(并且功能完全正常)。现在我可以加载HTML并使用此处发布的指令(Compiling dynamic HTML strings from database)对其进行编译。请参阅下面的代码。

问题

但是......当部分HTML已经加载(部分加载并正常运行)然后我从后端获得另一个HTML内容时,该指令正在编译新的,整个文档(DOM)得到了#34;冻结"。我无法输入输入或点击按钮,包括我之前加载的HTML中的按钮。

问题

我如何在"背景"中加载HTML内容,$compile或任何其他允许我继续使用其余(已经正常运行的)HTML的方式?

对我来说,必要的是,到达的新html内容会被编译,因为它包含角度验证等等,需要编译并进入角色世界" (在角度digest cycle内等等)。

这是我用来编译html的指令

(function () {

    var dynamic = function($compile) {
        return {
            restrict: 'A',
            replace: true,
            link: function (scope, ele, attrs) {
                scope.$watch(attrs.dynamic, function(html) {
                    if (html) {
                        ele.html(html);
                        $compile(ele.contents())(scope);
                    }

                });
            }
        };
    };

    dynamic.$inject = ['$compile'];

    angular.module('app')
        .directive('dynamic', dynamic);
}());

在控制器中我喜欢

// this will be filled with asynchronous calls were I get the HTMLs from a service
// in order to keep this example simple I just made a demo, not with the real async calls
$scope.secciones = []

//when the promises are getting resolved "secciones" would be something like (more items can be added after in time)
$scope.secciones = [
    {html: "<div> some html content here (not too small sometimes) </div>"},
    {html: "<div> another html content here (not too small sometimes) </div>"}
]

...并在视图中

<!--every time an async call with html is resolved, it's added to secciones, then a new div is generated and compiled-->
<!-- if there was some html previously rendered and the app starts compiling new html the UI gets "freezed"-->
<div ng-repeat="item in secciones">
    <div dynamic="item.html"></div>
</div>

注意:我使用这种方法,因为每个html代表我所拥有的一个标签页中的标签,其中用户实际上只看到了所有标签中的一个html&#34; secciones &#34; (其他的都是隐藏的,但仍然存在),但我需要编译其他的,以便在用户点击其他选项卡( secciones 中的另一个html)时为用户做好准备。< / p>

如果可以通过升级到更新版本的AngularJS(1.x)来解决这个问题,那么让我们说1.6。我很乐意尝试一下。

2 个答案:

答案 0 :(得分:2)

基本上我通过从脚本标记获取html并编译它并附加到现有div来完成此操作。 您可以使用以下代码段。

  

在html中加入div

<div id="step-container">

</div>
  

控制器代码

var template = $templateCache.get('basicInfo'); // or your html
$compile($("#step-container").html(template).contents())($scope);
$("#step-container").show();
  

为了演示,这将包含在html页面

<script type="text/ng-template" id="basicInfo"></script>

通过这种方式,您可以编译来自后端的html。

希望它有所帮助。

答案 1 :(得分:1)

您可以尝试使用此指令编译HTML代码。该指令编译代码何时检测变量htmlCode

中的任何更改
module.directive('bindHtmlCompile', ['$compile', function ($compile) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                scope.$watch(function () {
                    return scope.$eval(attrs.bindHtmlCompile);
                }, function (value) {
                    element.html(value && value.toString());
                    var compileScope = scope;
                    if (attrs.bindHtmlScope) {
                        compileScope = scope.$eval(attrs.bindHtmlScope);
                    }
                    $compile(element.contents())(compileScope);
                });
            }
        };
    }]);

您可以通过凉亭安装DirectiveRepo

用法:

<div bind-html-compile="htmlCode"></div>