我正在尝试创建一个接收模板和范围的打印提供程序,并将其编译为html,而不是在body标签中插入带有此html内容的iframe,并在iframe上的onload
事件上调用print打印此内容。
代码如下所示:
myApp.provider('$print', function() {
return {
$get: function($document, $interpolate, $compile, $timeout) {
var $print = {};
function printFrame(content) {
var frameContent = '<!doctype html>' +
'<html>' +
'<body onload="window.print()">' +
content +
'</body>' +
'</html>';
// inject iframe into DOM
var iframe = document.createElement("IFRAME");
iframe.id = 'print-frame';
iframe.style.display = 'none';
var body = $document.find('body').eq(0);
body.append(iframe);
iframe = document.getElementById('print-frame');
// fill iframe with print content
var iframeContent = (iframe.contentWindow) ? iframe.contentWindow : (iframe.contentDocument.document) ? iframe.contentDocument.document : iframe.contentDocument;
iframeContent.document.open();
iframeContent.document.write(frameContent);
iframeContent.document.close();
};
$print.iframe1 = function(printOptions) {
var printScope = printOptions.scope.$new();
var htmlToPrint = $interpolate(printOptions.template)(printScope);
printFrame(htmlToPrint);
}
$print.iframe2 = function(printOptions) {
var printScope = printOptions.scope.$new();
$timeout(function() {
var htmlToPrint = $compile(printOptions.template)(printScope);
printScope.$digest();
printFrame(htmlToPrint.html());
});
}
return $print;
}
}
});
我遇到的问题是,当我使用$interpolate
时,提供程序工作正常,iframe onload
事件等待,直到图像和所有内容在调用打印之前加载,但是我使用$compile
,出于某种原因,iframe的onload
事件会在加载图片之前触发。
我为这个例子创建了一个JSFiddle,如果你禁用缓存,你可以看到插值的方式,只在加载了大图像后才调用print,但是在编译时,打印信息会立即打开。
希望有人可以帮助我,提前谢谢,丹尼尔!
答案 0 :(得分:2)
htmlToPrint
确实有两个元素h1
&amp;另一个是img
标记,但问题是当您从htmlToPrint.html()
函数执行iframe2
时它只会返回SuperHero
,它不会返回html的其他部分。
为了解决这个问题,你可以使用你需要用一些div包装模板,这样在元素上执行.html()
时将返回正确的元素。
<强>模板强>
template: '<div>'+
'<h1>{{printTitle}}</h1>'+
'<img style="width: 1000px" src="http://velocityagency.com/wp-content/uploads/2013/08/go.jpg"'>+'
'<div>',
此外,您需要在10
函数中设置一些少量的超时,例如$timeout
。
$timeout(function() {
printFrame(htmlToPrint.html());
},10);
<强>更新强>
如果我禁用了浏览器缓存,上面的解决方案并不起作用,我想我们在页面上渲染图像之前会发送一个页面进行打印。
$print.iframe2 = function(printOptions, scope) {
var printScope = printOptions.scope.$new();
var htmlToPrint = $compile(printOptions.template)(printScope);
angular.element(htmlToPrint.find('img').on('load', function() {
$timeout(function() {
console.log("Img loaded")
printFrame(htmlToPrint.html());
});
}))
}