将角度模板编译为html的正确方法,将结果转换为字符串

A proper way to compile angular template into html, convert result into string

本文关键字:方法 字符串 转换 结果 html 编译      更新时间:2023-09-26

抽象

嗨,我

正在使用角度来渲染文档,我有一个视图模型,其中包含应该进入文档的数据,我有表示文档的角度模板。该模板是有效的 angular-html 标记,稍后使用 angular 的 $compile 呈现,这是我用于呈现文档以用于演示目的的指令:

angular.module('app').directive('render', function ($compile, server) {
    return {
        restrict: 'E',
        link: function ($scope, $element, $attributes) {
            var scope;
            server.resolve().then(function (repo) {
                var _template, _constants, _variables, _substitutes;
                var render = function () {
                    if (_template) {
                        $scope.repo = repo;
                        var references = repo.references;
                        if (_constants) {
                            for (var constantName in _constants) {
                                $scope[constantName] = references[_constants[constantName]];
                            }
                        }
                        if (_variables) {
                            for (var variableName in _variables) {
                                var substitute = _substitutes[variableName];
                                var variableValue = _variables[variableName];
                                var reference = repo.references[substitute];
                                if (reference) {
                                    if (reference.table === variableValue) {
                                        $scope[variableName] = reference;
                                    } else {
                                        throw new Error('Invalid reference type');
                                    }
                                }
                            }
                        }
                        if (scope) scope.$destroy();
                        scope = $scope.$new();
                        var element = angular.element('<div class="print"></div>');
                        element.html(_template);
                        $element.empty();
                        $element.append(element);
                        $compile(element)(scope);
                    }
                };
                $scope.$watch($attributes.template, function (template) {
                    _template = template;
                    render();
                });
                $scope.$watch($attributes.constants, function (constants) {
                    _constants = constants;
                    render();
                });
                $scope.$watch($attributes.variables, function (variables) {
                    _variables = variables;
                    render();
                });
                $scope.$watchCollection($attributes.substitutes, function (substitutes) {
                    _substitutes = substitutes;
                    render();
                });
            });
        }
    };
});

问题

我需要

制作文档的硬拷贝,换句话说,我需要将视图模型值替换为文档模板,将结果转换为字符串并将其放入变量中。我不能为此使用指令,angular的$compile调用功能真的很重,它在引擎盖下创建手表,我不需要整个shebang,我只需要替换值。最好的方法是什么?

提前谢谢你

有了你的$interpolate提示,我可以完成我的演示你的问题。

它没有将插值模板存储到数据库中的服务,以使演示专注于问题。

因此,据我了解,$compile$interpolate之间的区别如下:

  • $compile:创建与作用域有角度绑定的 DOM 元素。这就是您通常用于使 DOM 具有双向绑定等工作的方法。在大多数情况下,您不会手动调用它,因为如果您将templatetemplateUrl添加到 direcive 定义对象,它将自动$compile运行。

  • $interpolate:它与编译非常相似,唯一的区别是它将返回没有角度绑定的 DOM 元素。

如果您查看呈现的 html 标记,您可以看到差异。编译的模板在标记中ng-binding类,另一个只是静态 html,没有该类。

因此,正如您提到的$interpolate获取编译字符串的方法,您可以使用$http服务轻松将其存储在数据库中。

请看下面的演示或这个jsfiddle。

angular.module('myApp', [])
    .directive('render', Render);
var templateStore = [];
function Render($compile, $interpolate) {
    return {
        restrict: 'E',
        controllerAs: 'render',
        controller: function () {
            this.hello = 'hello from controller';
            //console.log($templateCache.get('testTemplate'));
            
        },
        compile: function (tElem, tAttrs) {
            return function (scope, element, attrs, controllers) {
                //controllers.hello = 'hello from controller';
                //console.log(controllers);
                var template = angular.element(
                    document.getElementById('template.html')).html(),
                    compiled = $compile(template)(scope),
                    obj = {
                        render: {
                            hello: "hello from 'fake' controller" 
                        },
                        hello: 'hello from other object.'
                    };
                scope.hello = "Hello from scope";
                element.replaceWith(compiled);
                var result = $interpolate(template)(scope);
                templateStore.push(result);
                var result = $interpolate(template)(obj);
                templateStore.push(result);
                //console.log(result);
                //console.log(templateStore[0]);
                $('#test').append( // append just to test the saved template
                    templateStore[0]);
                $('#test2').append( // append just to test the saved template
                    templateStore[1]);
             
            };
        }
    }
}
Render.$inject = ['$compile', '$interpolate'];
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
    <script type="text/ng-template" id="template.html">
        <div>
            <p>controllerAs: {{render.hello}}</p>
            scope: {{hello}}
        </div>
    </script>
    <h2>Compiled template with binding</h2>
    <render></render>
    
    <h2>The following is a string copy from above template with-out binding</h2>
    <div id="test"></div>
    <h2>You can also $interpolate a object with the following result (also no binding)</h2>
    <div id="test2"></div>
</div>