从后端渲染($ compile)html到视图中而不阻塞dom

lea*_*iro 5 html javascript dom compilation angularjs

CONTEXT

我需要在我的AngularJS(v1.4)应用程序中加载一些从后端获取的HTML并将其(html)插入到我的部分(已加载)中.部分已经加载了一些HTML(并且功能完全正常).现在我可以加载HTML并使用此处发布的指令编译它(从数据库编译动态HTML字符串).见下面的代码.

问题

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

我如何加载HTML内容,$compile它以"后台"或任何其他方式加载,以便我继续使用其余的(已经正常运行的)HTML?

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

这是我用来编译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);
}());
Run Code Online (Sandbox Code Playgroud)

在控制器中,我有类似的东西

// 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>"}
]
Run Code Online (Sandbox Code Playgroud)

......并且在视图中

<!--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>
Run Code Online (Sandbox Code Playgroud)

注意:我正在使用这种方法,因为每个html代表我所拥有的一个tabpanel中的一个标签,其中用户实际上只在" secciones "中看到所有这些标签的一个html (其他隐藏,但仍然存在),但我当他/她点击其他选项卡(secciones中的另一个html )时,需要编译其他人以便为用户做好准备.

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

Gha*_*han 2

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

在你的 html 中包含 div

<div id="step-container">

</div>
Run Code Online (Sandbox Code Playgroud)

控制器代码

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

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

<script type="text/ng-template" id="basicInfo"></script>
Run Code Online (Sandbox Code Playgroud)

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

希望能帮助到你。