10

I have created a directive for my application which is mentioned in the following question How do you serve a file for download with AngularJS or Javascript? Directive code is as like below

    appModule.directive('fileDownload', function ($compile) {
        var fd = {
            restrict: 'A',
            link: function (scope, iElement, iAttrs) {

                scope.$on("downloadFile", function (e, url) {
                    var iFrame = iElement.find("iframe");
                    if (!(iFrame && iFrame.length > 0)) {
                        iFrame = $("<iframe style='position:fixed;display:none;top:-1px;left:-1px;'/>");
                        iElement.append(iFrame);
                    }
                    iFrame.attr("src", url);
                });
            }
        };
        return fd;
    });

Here scope.$on is used, when I call this event via $scope.$emit or $scope.$broadcast, it is not working. My controller code is like below

    function reportsController($scope, $http) {
        var self = this;

        $scope.$broadcast("downloadFile", 'http://google.com');
        $scope.$emit("downloadFile", 'http://google.com');
    }

and my html file is as below

    <div ng-controller="reportsController" id="repctrl">
        <a file-download></a>
    </div>

What I am doing wrong here?

@Edit: Added the subscribe ($on) in the compile phase so as to avoid the usage of $timeout in controller. Here you can look the example

Kanagu
  • 606
  • 3
  • 9
  • 17

2 Answers2

7

I think your controller is being initialized before your directive.. so the $on starts listening after the $emit, $broadcast already happened.

see this plunker

open the console and you can see when the console.logs happen:

controller init happened script.js:16
link happened script.js:7
$scope.test() happened script.js:21
scope.$on happened script.js:9
scope.$on happened 

If you initialize the controller with ng-view or do the emit/broadcast after the directive is created, it should work.

Austin Greco
  • 32,997
  • 6
  • 55
  • 59
  • why are you doing a .controller on your returned fd object? – Nikos Dec 17 '13 at 15:34
  • fd is the return value of the 2nd argument of the directive function, which is just returning the directive config. The `.controller` is actually being called on the return value of `.directive`, which is a reference to the module that called it. – Austin Greco Dec 17 '13 at 17:15
1

something similar happen to me when i try to call a function in the directive of a modal,

what i had to do was to make a delay after I made the call to show the modal:

        $timeout(function () {
            $rootScope.$broadcast('obtiene-plantillas');
        }, 500);
Alfredo M
  • 568
  • 3
  • 7
  • 26
  • Here we don't need to give the time as second argument for $timeout. I have edited my question and added my latest finding as solution in the [fiddle](https://jsfiddle.net/esy4kLm2/5/) – Kanagu Jun 08 '17 at 10:35