Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

jquery - Append html content to an iframe in Angular JS

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 :).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...