7

I'm having a problem with a Iframe directive that I try to implement.

As far I am : Template:

<div class="externalIframe" iframe-src="external.html"></div>

Directive :

angular.module('project.directives', [])
   .directive('externalIframe', ['$rootScope', function($rootScope) {
      return {
        restrict: 'C',
        replace: true,
        transclude: true,
        scope: {
          src: '@iframeSrc', // the src uses the data-binding from the parent scope
        },
        template: '<iframe src="{{src}}" height="100%" width="100%" frameborder="0"></iframe>',
        link: function(scope, elem, attrs) {
          //elem.src = "dummy.html"; // not working either
        }
      }
    }])

Problem : It fires 2 HTTP request (2 iframe loading). :

  • one to http://localhost:8000/app/{{src}} (iframe src not yet interpreated by angular)
  • one to http://localhost:8000/app/external.html (iframe src once interpreated by angular)

I want to avoid the useless first call.. How can I do that ?

I tried without src in the template and programmatically set it in the link or compile function but that doesn't fire the iframe loading.

edit: jsFiddle added for bug demo with compile method => you'll see in the network tab of firebug/chrome dev panel that two request are made :

  • http://fiddle.jshell.net/_display/%7B%7Bsrc%7D%7D
  • http://fiddle.jshell.net/_display/external.html

Thanks for the help

3 Answers 3

8

You do not need a directive for this. Use ng-src on an actual iframe element. See the docs on ng-src.

<iframe ng-src="external.html"></iframe>
Sign up to request clarification or add additional context in comments.

4 Comments

Sure. You can do that. But it didn't solve the issue mentioned.
Can you explain to me: what did I miss? What is the difference with the mentioned issue? If you want a directive with an iframe, you can still use ng-src?
Using ng-src worked like a charm and made the two HTTP errors from the start disappear. I think the answer corresponds perfectly to the question.
Be careful with this, their is a bug in current ng-src implementation: github.com/angular/angular.js/issues/9843
5

Removing src from the iframe in the template and simply changing the attribute in the link function (via element.attr()) works:

return {
    restrict: 'E',
    require: '?ngModel',
    replace: true,
    transclude: true,
    template: '<iframe height="100%" width="100%" frameborder="0"></iframe>',
    link: function (scope, element, attrs) {
        element.attr('src', attrs.iframeSrc);
    }
};

Fiddle: http://jsfiddle.net/5rYrw/

1 Comment

Thanks for that, the element.attr( part was usefull.
1

Instead of using 'link' use the 'compile' function, as you're essentially wanting to modify the HTML before insertion into the DOM. I think 'link' is inserted, and then bound to the scope.

So with link 1. compile is called with {{url}} - request by iframe is made 2. link is called, and {{url}} is replaced, hence you second call.

If you use 'compile' you can modify the src attribute yourself.

Give http://docs.angularjs.org/guide/directive a look over, hope this helps

Edit Check this fiddle http://jsfiddle.net/jbSx6/20/

return {
    restrict: 'E',
    require: '?ngModel',
    replace: true,
    transclude: true,
    template: '<iframe src="%url%" height="100%" width="100%" frameborder="0"></iframe>',
    compile: function (element, attrs, transclude) {
        console.log(element[0].outerHTML);
        element[0].outerHTML = element[0].outerHTML.replace('%url%',attrs.iframeSrc);
        console.log(element);
    }
};

<div ng-app="myApp">
   <div>display google in frame</div>
   <my-frame data-iframe-src="http://jsfiddle.net">test</my-frame>
</div>

3 Comments

Hi thanks for your help, but I tried it without success. See my edit/jsfiddle for the details.
Hi Bixi - it does work, in that fiddle you were still using the link function, not compile. Please see my edit.
This is definitely the "Angular way" of solving the problem. Good answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.