将 html 内容附加到 Angular JS 中的 iframe [英] Append html content to an iframe in Angular JS

查看:24
本文介绍了将 html 内容附加到 Angular JS 中的 iframe的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个完整的 html 文档的预览,这意味着这个 html 内容本身就是一个完整的 html 文档,带有 , 标签.

如果我只是将该 html 文档加载到我现有的 html 根目录中,那么所有样式都将被新包含的 html 文档中定义的样式覆盖.如果我在 src (<iframe e src="path/to/doc.html">) 上包含这个带有 iframe 的 html 文档,那么它就可以工作了.但是,这个 doc.html 是一个模板,我需要在其中替换我用自定义标签注释的某些部分.我通过执行以下代码来做到这一点

$.get('template/template.html', function (template) {String.prototype.format = function () {var args = 参数;this.unkeyed_index = 0;return this.replace(/\{(\w*)\}/g, function (match, key) {如果(键 === ''){键 = this.unkeyed_index;this.unkeyed_index++}如果(键 == + 键){返回 args[key] !== 'undefined'?参数[键]: 比赛;} 别的 {for (var i = 0; i < args.length; i++) {if (typeof args[i] === 'object' && typeof args[i][key] !== 'undefined') {返回 args[i][key];}}返回匹配;}}.bind(this));};var renderHtml = template.format({hello: "hey there"});});

到目前为止,这工作正常.在变量 renderedHtml 中,我有完整的 html 文档,并且正在替换占位符(在这种情况下,占位符 hello 被替换为hey there".

不,我有以下 html 片段

我尝试了以下代码:

 var elem = document.createElement('div');elem.innerHTML = renderHtml;document.getElementById('test').appendChild(elem);$compile(elem)($scope);

不幸的是,视图没有任何变化.但是,如果我在 document.body 上调用 appendChild(elem) 那么它就可以工作了.有谁知道可能是什么问题?

附言我知道你不应该在你的 angular 控制器中做 DOM 操作,而不是 $compile 你应该用指令来做.但是,如果这种方式有效,那么我很乐意尝试将其重构为指令 :)

解决方案

我不得不做一些类似于你正在做的事情.我需要为一些 HTML 模板制作一个编辑器.由于现有站点中的 CSS,模板预览效果不佳,所以我想在 iframe 中显示模板.

我能够制作一个带有手表的角度指令,它会更新:iframe.contentDocument.body.innerHTML 并得到我想要的效果.我相信您可以截取此处的内容并替换模板中的占位符.

下面的 preview 指令应该可以帮助您,如果您在这段时间之后仍然需要它.

var app = angular.module('App',[]);app.controller("Cont", function($scope){$scope.content = "你好!";});app.directive(预览",函数(){功能链接(范围,元素){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;});}返回 {链接:链接,限制:'E',范围: {内容:'='}};});

input, iframe {边框:纯 1px 黑色;宽度:100px;}预览 iframe {高度: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="内容"></preview>

I am trying to create a preview of a full fledged html document, meaning this html content is itself a complete html document with <html>, <head>, <body> tags.

If I would just load that html document into my existing html root, then all styles will be overridden by the ones defined in the newly included html doc. If I include this html document with an iframe over src (<ifram e src="path/to/doc.html">) then it works. However, this doc.html is a template where I need to replace certain parts which I have annotated with custom tags. I am doing this by executing the following code

$.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"});
});

So far this works fine. In the variable renderedHtml I have my complete html document and the placeholders are being replaced (in this case the placeholder hello is being replaced with "hey there".

No I have the following html snippet

<iframe id="test"></iframe>

and I tried the following code:

  var elem = document.createElement('div');
  elem.innerHTML = renderedHtml;
  document.getElementById('test').appendChild(elem);
  $compile(elem)($scope);

Unfortunately, nothing changes on the view. However, if I call appendChild(elem) on document.body then it works. Does anyone know what the problem could be?

P.S. I know that you should not do DOM manipulations in your angular controller and instead of $compile you should do it with a directive. However, if this way works then I am happy to try to refactor it to a directive :).

解决方案

I had to do something similar to what you're doing. I needed to make an editor for some HTML templates. The templates didn't preview well due to the CSS in the existing site, so I thought to display the template in an iframe.

I was able to make an angular directive with a watch in it which would update: iframe.contentDocument.body.innerHTML and got me my desired effect. I believe you would be able to intercept the content here and make any replacements for placeholders inside your template as well.

The preview directive below should help you on your way, if you still need it after all this time.

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>

这篇关于将 html 内容附加到 Angular JS 中的 iframe的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆