我正在尝试创建一个完整的html文档的预览,这意味着这个html内容本身就是一个包含<html>
,<head>
,<body>
标签的完整html文档。
如果我只是将该html文档加载到我现有的html根目录中,那么所有样式都将被新包含的html doc中定义的样式覆盖。如果我将这个带有iframe的html文档包含在src(<ifram e src="path/to/doc.html">
)上,那么它可以工作。但是,这个doc.html是一个模板,我需要替换我用自定义标签注释的某些部分。我这样做是通过执行以下代码
$.get('template/template.html', function (template) {
String.prototype.format = function () {
var args = arguments;
this.unkeyed_index = 0;
return this.replace(/\{(\w*)\}/g, function (match, key) {
if (key === '') {
key = this.unkeyed_index;
this.unkeyed_index++
}
if (key == +key) {
return args[key] !== 'undefined'
? args[key]
: match;
} else {
for (var i = 0; i < args.length; i++) {
if (typeof args[i] === 'object' && typeof args[i][key] !== 'undefined') {
return args[i][key];
}
}
return match;
}
}.bind(this));
};
var renderedHtml = template.format({hello: "hey there"});
});
到目前为止这个工作正常。在变量renderedHtml
中,我有完整的html文档,占位符正在被替换(在这种情况下,占位符问候语被替换为“嘿那里”。
不,我有以下html代码段
<iframe id="test"></iframe>
我尝试了以下代码:
var elem = document.createElement('div');
elem.innerHTML = renderedHtml;
document.getElementById('test').appendChild(elem);
$compile(elem)($scope);
不幸的是,视图没有任何变化。但是,如果我在appendChild(elem)
上拨打document.body
,那就可以了。有谁知道问题可能是什么?
P.S。我知道你不应该在角度控制器中进行DOM操作,而不是$ compile,你应该用指令来做。但是,如果这种方式有效,那么我很乐意尝试将其重构为指令:)。
答案 0 :(得分:9)
我必须做一些类似于你正在做的事情。我需要为一些HTML模板创建一个编辑器。由于现有网站中的CSS,模板没有很好地预览,所以我想在iframe中显示模板。
我能够制作一个带有手表的角度指令,它会更新:iframe.contentDocument.body.innerHTML
并获得我想要的效果。我相信您可以在此拦截内容,并在模板中替换占位符。
下面的预览指令可以帮助您,如果您在此之后仍然需要它。
var app = angular.module('App',[]);
app.controller("Cont", function($scope){
$scope.content = "Hi there!";
});
app.directive("preview", function () {
function link(scope, element) {
var iframe = document.createElement('iframe');
var element0 = element[0];
element0.appendChild(iframe);
var body = iframe.contentDocument.body;
scope.$watch('content', function () {
body.innerHTML = scope.content;
});
}
return {
link: link,
restrict: 'E',
scope: {
content: '='
}
};
});
&#13;
input, iframe {
border: solid 1px black;
width: 100px;
}
preview iframe {
height: 50px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="App" ng-controller="Cont">
<input ng-model="content" type="text" /><br />
<preview content="content"></preview>
</div>
&#13;
答案 1 :(得分:0)
基于Chris针对Firefox浏览器存在问题的解决方案的更新解决方案:
var app = angular.module('App',[]);
app.controller("Cont", function($scope){
$scope.content = "Hi there!";
});
app.directive("preview", function () {
function link(scope, element) {
var iframe = document.createElement('iframe');
var element0 = element[0];
element0.appendChild(iframe);
scope.$watch('content', function () {
iframe.contentWindow.document.open('text/htmlreplace');
iframe.contentWindow.document.write(scope.content);
iframe.contentWindow.document.close();
});
}
return {
link: link,
restrict: 'E',
scope: {
content: '='
}
};
});