将 html 内容附加到 Angular JS 中的 iframe
Posted
技术标签:
【中文标题】将 html 内容附加到 Angular JS 中的 iframe【英文标题】:Append html content to an iframe in Angular JS 【发布时间】:2014-03-29 15:41:23 【问题描述】:我正在尝试创建一个完整的 html 文档的预览,这意味着这个 html 内容本身就是一个带有<html>
、<head>
、<body>
标签的完整 html 文档。
如果我只是将该 html 文档加载到我现有的 html 根目录中,那么所有样式都将被新包含的 html 文档中定义的样式覆盖。如果我在 src (<ifram e src="path/to/doc.html">
) 上包含这个带有 iframe 的 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 文档,并且占位符正在被替换(在这种情况下,占位符 hello 被替换为“hey there”。
不,我有以下 html sn-p
<iframe id="test"></iframe>
我尝试了以下代码:
var elem = document.createElement('div');
elem.innerHTML = renderedHtml;
document.getElementById('test').appendChild(elem);
$compile(elem)($scope);
不幸的是,视图没有任何变化。但是,如果我在document.body
上调用appendChild(elem)
,那么它可以工作。有谁知道可能是什么问题?
附:我知道你不应该在你的角度控制器中做 DOM 操作,而不是 $compile 你应该用一个指令来做。但是,如果这种方式可行,那么我很乐意尝试将其重构为指令:)。
【问题讨论】:
【参考方案1】:我不得不做一些类似于你正在做的事情。我需要为一些 HTML 模板制作一个编辑器。由于现有网站中的 CSS,模板没有很好地预览,所以我想在 iframe 中显示模板。
我能够制作一个带有手表的角度指令,它会更新:iframe.contentDocument.body.innerHTML
并得到我想要的效果。我相信您将能够截取此处的内容,并对模板中的占位符进行任何替换。
下面的 preview 指令应该可以帮助您,如果您在这段时间之后仍然需要它。
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: '='
;
);
input, iframe
border: solid 1px black;
width: 100px;
preview iframe
height: 50px;
<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>
【讨论】:
为什么指令中需要这段代码** content: '=' ** 虽然是一个(相对)旧的解决方案,但我在我的应用程序中很好地使用了它来在 iframe 中显示模板渲染的内容。但是,我刚刚开始在 FireFox 中查看这个,我只是得到一个空白的 iFrame。任何想法为什么会这样? @BrendanGreen 查看我基于 Chris 的解决方案,该解决方案也适用于 firefox【参考方案2】:基于 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: '='
;
);
【讨论】:
以上是关于将 html 内容附加到 Angular JS 中的 iframe的主要内容,如果未能解决你的问题,请参考以下文章