Javascript 以编程方式将角度模板编译为HTML字符串
在我的Angular 1.5.11应用程序中,我试图以编程方式编译一个模板,并将结果作为HTML字符串。模板的内容是Javascript 以编程方式将角度模板编译为HTML字符串,javascript,angularjs,Javascript,Angularjs,在我的Angular 1.5.11应用程序中,我试图以编程方式编译一个模板,并将结果作为HTML字符串。模板的内容是 <div ng-if="foo"> <div>foo is {{foo}}, bar is {{bar}}</div> </div> foo是{{foo}},bar是{{bar} 我试图将其编译为HTML字符串: app.controller('MainCtrl', function($scope, $rootScope
<div ng-if="foo">
<div>foo is {{foo}}, bar is {{bar}}</div>
</div>
foo是{{foo}},bar是{{bar}
我试图将其编译为HTML字符串:
app.controller('MainCtrl', function($scope, $rootScope, $compile) {
function compileHtmlTemplate (templateContent, model) {
var templateScope = $rootScope.$new(true);
angular.extend(templateScope, model);
return $compile(templateContent)(templateScope);
}
var templateContent = $('#template').html();
var model = {foo: 'fooValue', bar: 'barValue'};
var compiledHtml = compileHtmlTemplate(templateContent, model);
var htmlAsString = $('<div></div>').html(compiledHtml).html();
$scope.result = htmlAsString;
});
app.controller('MainCtrl',函数($scope、$rootScope、$compile){
函数compileHtmlTemplate(模板内容、模型){
var templateScope=$rootScope.$new(true);
角度扩展(模板范围、模型);
返回$compile(templateContent)(templateScope);
}
var templateContent=$('#template').html();
var模型={foo:'fooValue',bar:'barValue'};
var compiledHtml=compileHtmlTemplate(模板内容,模型);
var htmlAsString=$('').html(compiledHtml.html();
$scope.result=htmlastring;
});
但是,正如您在本文中看到的,它不起作用。我需要编译模板,而不仅仅是插入模板,因为它包含一个
ng if
指令。是的,您可以像这样使用$interpolate
var app = angular.module('plunker', ['ngSanitize']);
app.controller('MainCtrl', function($scope, $rootScope, $compile, $interpolate) {
function compileHtmlTemplate (templateContent, model) {
var templateScope = $rootScope.$new(true);
angular.extend(templateScope, model);
var tpl = $compile(templateContent)(templateScope);
console.log(tpl);
return $interpolate(tpl.html(),model)
}
var templateContent = $('#template').html();
var model = {foo: 'fooValue', bar: 'barValue'};
var compiledHtml =compileHtmlTemplate(templateContent)(model);
//console.log(compiledHtml)
var htmlAsString = $('<div></div>').html(compiledHtml).html();
$scope.result = htmlAsString;
});
var-app=angular.module('plunker',['ngSanitize']);
app.controller('MainCtrl',函数($scope、$rootScope、$compile、$interpolate){
函数compileHtmlTemplate(模板内容、模型){
var templateScope=$rootScope.$new(true);
角度扩展(模板范围、模型);
var tpl=$compile(templateContent)(templateScope);
控制台日志(tpl);
返回$interpolate(tpl.html(),model)
}
var templateContent=$('#template').html();
var模型={foo:'fooValue',bar:'barValue'};
var compiledHtml=compileHtmlTemplate(模板内容)(模型);
//console.log(compiledHtml)
var htmlAsString=$('').html(compiledHtml.html();
$scope.result=htmlastring;
});
使用模型插值返回已编译的html,然后使用相同的方法
$compile返回的元素不是html字符串
Angular的摘要周期需要完成,然后才能访问该值。您可以通过使用
$timeout
来实现这一点
我使用了$templateCache
来检索模板,因为这是官方的方式,但这只是个人偏好
var app = angular.module('plunker', ['ngSanitize']);
app.controller('MainCtrl', function($scope, $rootScope, $compile, $timeout, $templateCache) {
function compileHtmlTemplate (templateContent, model) {
var templateScope = $rootScope.$new(true);
angular.extend(templateScope, model);
var compiled = $compile(templateContent)(templateScope);
var parent = $("<div>").html(compiled);
console.log("Won't work! Digest hasn't finished:", parent[0].innerHTML);
$timeout(function(){ // must wait till Angular has finished digest
console.log('Will work, digest has now completed:', parent[0].innerHTML);
$scope.result = parent[0].innerHTML;
}, 0);
}
// either do something with the compiled value within the $timeout, or watch for it
$scope.$watch('result', function(newValue, oldValue) {
if (newValue !== undefined) {
console.log("Do something in the $timeout or here... " + newValue);
}
});
// you can access the template via the template cache if you wanted
var templateContent = $templateCache.get('template');
var model = {foo: 'fooValue', bar: 'barValue'};
var compiledHtml = compileHtmlTemplate(templateContent, model);
});
var-app=angular.module('plunker',['ngSanitize']);
app.controller('MainCtrl',函数($scope、$rootScope、$compile、$timeout、$templateCache){
函数compileHtmlTemplate(模板内容、模型){
var templateScope=$rootScope.$new(true);
角度扩展(模板范围、模型);
var compiled=$compile(templateContent)(templateScope);
var parent=$(“”).html(已编译);
console.log(“不起作用!摘要尚未完成:”,父[0].innerHTML);
$timeout(function(){//必须等待Angular完成摘要
console.log('将起作用,摘要现在已完成:',父项[0].innerHTML);
$scope.result=parent[0]。innerHTML;
}, 0);
}
//要么在$timeout内对编译后的值执行某些操作,要么观察它
$scope.$watch('result',函数(newValue,oldValue){
if(newValue!==未定义){
log(“在$timeout或此处执行操作…”+newValue);
}
});
//如果需要,可以通过模板缓存访问模板
var templateContent=$templateCache.get('template');
var模型={foo:'fooValue',bar:'barValue'};
var compiledHtml=compileHtmlTemplate(模板内容,模型);
});
更新的Plunker:如果你想显示HTML,你不能简单地使用
{{}
,你需要使用ng bind HTML
或使用angular的$sanitaze
服务
我已经更新了你的装备
var compiledHtml=compileHtmlTemplate(模板内容,模型);
var element=angular.element(“”).html(compiledHtml)
$timeout(函数(){
$scope.result=element.html()
})
由于模板中的
ngIf
,因此compiledHtml
仅返回ngIf
注释,我以前也曾遇到过这种情况,我提出的唯一解决方案就是如上所述,将compiledHtml
附加到新创建的元素中,并在$timeout
中检索html,而不指定时间,因为这将在附加和$digest
循环之后发生。希望对您有所帮助下面是您代码的工作版本(大多数更改都与以角度方式做事相关)
var templateContent=$templateCache.get(“模板”);
//var templateContent=$('#template').html();
//注释:以角度方式获取html,而不是使用jquery
var模型={foo:'fooValue',bar:'barValue'};
var templateScope=$rootScope.$new(true);
templateScope=angular.extend(templateScope,模型);
//角度扩展(模板范围、模型);
//注释:确保捕获angular.extend的结果
var compiledElement=$compile(templateContent)(templateScope);
//var compiledHtml=$compile(templateContent)(templateScope);
//注释:编译的结果不是一个html,而是一个角度元素
var targetElement=angular.element(“结果”);
//var htmlAsString=$('').html(compiledHtml.html();
//注释:使用angular而不是jquery查找元素
targetElement.append(compiledElement);
//$scope.result=htmlastring;
//注释:不要只指定字符串,还要附加一个角度元素
更新
html中的一个小变化是
replaced
<div>{{result}}</div>
with
<div id="result"></div>
已替换
{{result}}
具有
想发明轮子吗?或者你想得到什么?正如您在上一个问题中所评论的,您可能希望$interpolate而不是$compile。您需要$eval后面的值compiling@PetrAveryanov$interpolate
无法工作,因为模板包含directives@blackmiaoolfoo
有一个值,因此如果ng
的计算结果为true.@estus OP没有说它没有用,有效问题;只是他们不想进一步解释。那完全是他们的特权。例如,细节可能是商业敏感的。而且,在10万美元的时候,它们已经存在了足够长的时间
var templateContent = $templateCache.get("template");
//var templateContent = $('#template').html();
//comment: get html in angular way, not using jquery
var model = {foo: 'fooValue', bar: 'barValue'};
var templateScope = $rootScope.$new(true);
templateScope = angular.extend(templateScope, model);
//angular.extend(templateScope, model);
//comment: make sure to capture result of angular.extend
var compiledElement = $compile(templateContent)(templateScope);
//var compiledHtml = $compile(templateContent)(templateScope);
//comment: result of compilation is not an html but an angular element
var targetElement = angular.element("#result");
//var htmlAsString = $('<div></div>').html(compiledHtml).html();
//comment: find the element using angular and not jquery
targetElement.append(compiledElement);
//$scope.result = htmlAsString;
//comment: don't just assign string, append an angular element
replaced
<div>{{result}}</div>
with
<div id="result"></div>