【问题标题】:scope.$on is not working when created inside a directivescope.$on 在指令中创建时不起作用
【发布时间】:2013-12-17 07:15:55
【问题描述】:

我为我的应用程序创建了一个指令,该指令在以下问题中提到 How do you serve a file for download with AngularJS or Javascript? 指令代码如下

    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;
    });

这里使用了 scope.$on,当我通过 $scope.$emit 或 $scope.$broadcast 调用此事件时,它不起作用。我的控制器代码如下所示

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

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

我的html文件如下

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

我在这里做错了什么?

@Edit:在编译阶段增加了订阅($on),以避免在控制器中使用$timeout。 Here你可以看例子

【问题讨论】:

    标签: angularjs events broadcast directive emit


    【解决方案1】:

    我认为你的控制器在你的指令之前被初始化。所以$on$emit$broadcast已经发生之后开始监听。

    看到这个plunker

    打开控制台,你可以看到console.logs发生的时间:

    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 
    

    如果您使用ng-view 初始化控制器或在创建指令后进行发射/广播,它应该可以工作。

    【讨论】:

    • 你为什么要在你返回的 fd 对象上做一个 .controller?
    • fd 是指令函数的第二个参数的返回值,它只是返回指令配置。 .controller 实际上是在 .directive 的返回值上调用的,这是对调用它的模块的引用。
    【解决方案2】:

    当我尝试在模态指令中调用函数时,类似的事情发生在我身上,

    我必须做的是在我拨打电话以显示模式后进行延迟:

            $timeout(function () {
                $rootScope.$broadcast('obtiene-plantillas');
            }, 500);
    

    【讨论】:

    • 这里我们不需要将时间作为 $timeout 的第二个参数。我已经编辑了我的问题并将我的最新发现作为解决方案添加到 fiddle
    猜你喜欢
    • 1970-01-01
    • 2015-08-31
    • 2016-04-11
    • 1970-01-01
    • 2015-12-13
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多