10

I am writing an application which is part Angular and part jQuery. I am separating them by loading the jQuery content in an iFrame.

Upon a certain event (say, upon a ng-click), I need to refresh the iFrame. My Controller contains the following code:

$scope.refreshIframe = function() { //refresh the iFrame with id "anIframe" };

and the iFrame is:

<iframe id="anIframe" src="myUrl"></iframe>
harriyott
  • 10,505
  • 10
  • 64
  • 103
Amarsh
  • 11,214
  • 18
  • 53
  • 78

5 Answers5

12

As Paulo Scardine said, the right way to do it would be through a directive cause you shouldn't use controllers to manipulate DOM.

Something like this one could do :

.directive('refreshable', [function () {
    return {
        restrict: 'A',
        scope: {
            refresh: "=refreshable"
        },
        link: function (scope, element, attr) {
            var refreshMe = function () {
                element.attr('src', element.attr('src'));
            };

            scope.$watch('refresh', function (newVal, oldVal) {
                if (scope.refresh) {
                    scope.refresh = false;
                    refreshMe();
                }
            });
        }
    };
}])

Which could then be used like :

<iframe refreshable="tab.refresh"></iframe>

And :

$scope.refreshIframe = function(){
    $scope.tab.refresh = true;
}
Florian F.
  • 4,700
  • 26
  • 50
  • When I try this, I get an error stating that "TypeError: Cannot set property 'refresh' of undefined" Do you need to define "tab" in a special way? – Victor Oct 14 '15 at 10:20
  • No, just go with `$scope.tab = {};` on controller init. You can also use another variable like `$scope.whateveryouwant`. – Florian F. Oct 14 '15 at 17:00
  • Thanks Florian. Variable initialization was indeed missing! – Victor Oct 15 '15 at 07:16
  • This isn't working when the src of the iframe is dynamically loaded with ng-src. I believe that angular will only reload the iframe if the value changes, and setting the value with the current value does not result in an reload – AnxiousdeV Aug 18 '19 at 04:57
7

Another hack-ish solution: if you don't want to create a directive but want to stick to the good practices of not manipulating the DOM in controller. Keep the url in an array and use ng-repeat to render the iFrame: View:

<iframe ng-repeat="url in vm.url" ng-src="{{url}}" />

Controller:

vm.url = ['http://google.com'];

So, every time you set the value of the vm.url, angular will re-render the iFrame.

1

Solved it by a hack suggested in Reload an iframe with jQuery

$scope.refreshIframe = function() { 
    var iFrame = $document.find("anIframe");
    iFrame.attr("src",iFrame.attr("src"));
};
harriyott
  • 10,505
  • 10
  • 64
  • 103
Amarsh
  • 11,214
  • 18
  • 53
  • 78
0

If you want to refresh all iframes from your page :

    var refreshAllIframes = function(){
      var iFrames = $document.find('iframe');
      for(var i = 0; i < iFrames.length; i++){
        refreshFrame(i,iFrames);
      }
    }

    var refreshFrame = function(i,iFrames){
      iFrames[i].src = iFrames[i].src;
    }
Emidomenge
  • 1,172
  • 17
  • 26
0

I did it in Angular 2 like that:

import { Component, ViewChild, ElementRef } from '@angular/core';
@Component({
    selector: 'myHTMLContainer',
    template: `<iframe #ifr ></iframe>`
    })

export class HTMLContainerComponent implements OnInit {
    @ViewChild('ifr') ifr: ElementRef;
    
    //call setURL function whenever you want to change the iframe's src
    setURL(url:string) {
        this.ifr.nativeElement["src"] = url;
    }