[英]A proper way to compile angular template into html, convert result into string
Hi, I'm using angular to render documents, I have the view-model that contains the data which should go into document, and I have angular template that represents the document. 嗨,我使用角度渲染文档,我有视图模型,其中包含应该进入文档的数据,我有角度模板,代表文档。 The template is valid angular-html markup that is later rendered using angular's $compile , here is directive I use to render documents for presentation purposes:
该模板是有效的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();
});
});
}
};
});
I need to make a hard-copy of the document, in other words I need to substitute the view-model values into document template, convert result into string and put it into variable. 我需要制作文档的硬拷贝,换句话说,我需要将视图模型值替换为文档模板,将结果转换为字符串并将其放入变量中。 I can't use directive for that, angular's $compile is really heavy function to call, it creates watches under the hood, I don't need whole shebang, I just need to substitute values.
我不能使用指令,angular的$ compile实际上是很重要的函数调用,它创建了引擎盖下的手表,我不需要整个shebang,我只需要替换值。 What would be the best way to do that?
最好的方法是什么?
Thank you in advance 先感谢您
With your tip for $interpolate
I could finalize my demo for your question. 有了
$interpolate
的提示,我可以为你的问题完成我的演示。
It's with-out a service for storing the interpolated template into database to keep the demo focused on the issue. 它没有用于将插值模板存储到数据库中的服务,以使演示集中在该问题上。
So as I've understood, the difference between $compile
and $interpolate
is the following: 正如我所理解的,
$compile
和$interpolate
之间的区别如下:
$compile
: Creates DOM elements with angular binding to scope. $compile
:使用与范围的角度绑定创建DOM元素。 That's what you would normally use to render your DOM to have two-way binding etc. working. 这就是您通常用于渲染DOM以使双向绑定等工作的内容。 In most cases you don't call it manually because if you add
template
or templateUrl
to the direcive definition object it will run $compile
automatically. 在大多数情况下,您不会手动调用它,因为如果将
template
或templateUrl
添加到direcive定义对象,它将自动运行$compile
。
$interpolate
: It is pretty similar to compile with the only difference that it will return the DOM elements wiht-out angular bindings. $interpolate
:它与编译非常相似,唯一的区别是它将返回带有角度绑定的DOM元素。
You can see the difference if you have a look at the rendered html markup. 如果你看一下渲染的html标记,你可以看到差异。 Compiled templates have
ng-binding
class in the markup and the other is just static html with-out that class. 编译模板在标记中有
ng-binding
类,另一个只是静态html而没有该类。
So as you mentioned $interpolate
is the way to go to get the compiled string that you can easily store in the database with a $http
service. 因此,正如您所提到的,
$interpolate
是获取编译字符串的方法,您可以使用$http
服务轻松存储在数据库中。
Please have a look at the demo below or at this jsfiddle . 请看下面的演示或这个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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.