Jscti
Jscti

Reputation: 14440

Angular : src attribute bug in Iframe directive

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

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 :

Thanks for the help

Upvotes: 7

Views: 15323

Answers (3)

markmarijnissen
markmarijnissen

Reputation: 5887

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>

Upvotes: 8

tdakhla
tdakhla

Reputation: 670

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/

Upvotes: 5

leon.io
leon.io

Reputation: 2824

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>

Upvotes: 1

Related Questions