0

I'm starting with AngularJS and I need to bind "load" and "error" events to the iframes:

<ul  data-ng-controller="WebServicesCtrl">
    <li data-ng-repeat="webservice in webservices">
        <a href="{{webservice.wsdl}}">{{webservice.name}}</a>

        <iframe src="{{webservice.wsdl}}" class="hidden"></iframe>

    </li>
</ul>

I tried to use $scope.watch and $scope.apply without success. I need to bind events right on iframe creation, since it will autoload the given src. Something like this:

app.controller('WebServicesCtrl', function WebServicesCtrl($scope, $http) {

    $http.get('/webservices').success(function(data /* from expressjs, yaaay! */) {

        $scope.webservices = data;

        /* make iframes listen to load and error right after scope change,
           before AngularJS inject them. */
    }); 

});

I MUST NOT use <iframe onload="" onerror="" />. I would like to know the jQuery form. The "pure AngularJS" case is welcome too. Just don't recall that jQuery is not needed. Sometimes we got huge legacy and things can't be beautiful.

Should I use $injector or something like that? That documentation is so young that hurts. Feel like I'll have to study the source code soon.

1 Answer 1

4

Your best option is to use a directive wrapping around these two tags.

<a href="{{webservice.wsdl}}">{{webservice.name}}</a>

<iframe src="{{webservice.wsdl}}" class="hidden"></iframe>

Define something like:

app.directive("aIframe", function () {
   return {
      template: '<div><a href="{{webservice.wsdl}}">{{webservice.name}}</a>' +
                '<iframe src="{{webservice.wsdl}}" class="hidden"></iframe></div>',
      restrict: 'A',
      scope: {
         webservice: '=webService'
      },
      link: function(scope, element, attrs) {
         $(element).find("iframe").on("load", function () {
         //some code
         });
         $(element).find("iframe").on("error", function () {
         //some code
         });
      }
   };
});

The advantage with using the link function is that, it will run on each time the directive is initialized an it will run right after the scope bindings are done from the ng-repeat scope.

Your HTML will now change as:

<ul  data-ng-controller="WebServicesCtrl">
    <li data-ng-repeat="webservice in webservices">
        <div a-iframe web-service="webservice"></div>
    </li>
</ul>

More about directives, and it's parameters, here: AngularJS: Directives

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you a lot, @PraveenramBalachandar! I think this will do the job. Just for curiosity, is there any other "common" way? I just realized I would take some painful days till this solution so knowing similarities is wise.
The general guideline in angularJS is to wrap controls into directives so you have more control over the elements. Especially in cases similar to yours. Plus it gives you the ability to use this in pretty much any controller, not just limited to this html structure. If you want to bind events to elements rendered by angular this is the best and cleanest approach, and the "common" way :)

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.