【问题标题】:Calling a function defined in a directive's scope from a controller从控制器调用指令范围内定义的函数
【发布时间】:2015-04-26 22:59:21
【问题描述】:

编辑:我创建了一个 Plnkr http://plnkr.co/edit/yuvtrPs3csAQZW7OF06O

我不确定这是否有任何关系,但我注意到控制台的日志显示:

事件跟踪多窗格显示预览工具栏 undefined undefined


前提:我正在根据链接中的“可能被遗忘”的问题创建一个新问题:

AngularJS: How do I call a function defined in a directive's scope from a controller?

由于我在那里得到了一个答案,我将新问题告知他,以防他想在这里完成他的答案。 另外,我知道有类似的问题,但我找不到适合我的情况的解决方案。

我需要调用一个属于我的 Angular 应用程序中使用的 ng 指令的 $scope 的函数。 按照教程:

http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

我设置以下代码为例。

假设指令是这样定义的:(具体来说,指令——在这里简化——是插件定义的指令:www.ixtendo.com/polyglot-language-switcher-2/#angularjs)

注意:指令和我想要访问指令的控制器功能的控制器之间存在not父子关系。这就是我使用 $rootScope

的原因
.directive('my-directive', ['$document', '$timeout', '$rootScope', function ($document, $timeout, $rootScope) {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            // ....
        },
        controller: ['$scope', '$rootScope', function ($scope, $rootScope) {

            var myFunction= function () {
                // do something...
            };

            $scope.$on('openLanguageSelectionPopup', function (){
                console.log("event triggered"); // NOT triggered!
                myFunction();  
            });
        }
    };
}]);

我需要从我的控制器(称为 ma​​inController)调用 myFunction,这是放置我的指令的视图的控制器。我将其定义为:

.controller('mainController',
function ($scope, $rootScope){
    $rootScope.$emit('openLanguageSelectionPopup'); 
    // this is event should be received by any $rootScope.$on(...) in ANY controller
})

我修改了指令的控制器本身但没有成功

事实上,事件 (openLanguageSelectionPopup) 没有被触发(console.log 没有被打印)。 我也确信 $on 和 $emit 都会在某个时候达到(我尝试使用 console.log(...) )。

我了解问题可能出在指令的范围定义中,正如以下答案中提出的解决方案:

Calling a method in a controller defined in a directive from a javascript function

但是,如果这是问题所在,我无法理解接受的答案会对我的具体案例带来什么。

另外,我不明白应该将 $rootScope: 放在指令的控制器函数还是指令的定义函数中(在我的示例中,我在这两个函数中都添加了它)。

【问题讨论】:

  • 您在指令控制器中收听 'closeLanguageSelectionPopup' 而不是 'openLanguageSelectionPopup'。这有什么改变吗?
  • 我很抱歉。事实上,我有两个不同的听众,但如果我知道如何解决一个,我会同时解决两个。问题已编辑(也许有办法分析哪些控制器实际上能够接收特定事件?)
  • 您不应该使用 $rootScope.$broadcast 吗,因为 emit 在范围树中上升,所以它最终到达 rootScope,但您已经在 rootScope 启动它。但是,您可以使用 $scope.$emit 来实现相同的功能。
  • 请尝试$broadcast 而不是$emit,因为$broadcast 将通道向下延伸到您的子范围,它应该到达您的指令范围
  • 在我的例子中 $broadcast 和 $emit 在与 $rootScope 一起使用时应该是等效的(根据提到的教程)。但是我也尝试使用 $broadcast 。结果相同

标签: angularjs


【解决方案1】:

你在控制器中发射和广播你的东西。 但该指令不存在。

至少我认为这正在发生。 因为如果我将您的广播包装在超时中,他们就会收到它。

你的 plunkr 也缺少一些东西

您忘记将脚本添加到 index.html 你像这样在 html 中调用你的指令,但它应该是

【讨论】:

  • 你是对的。由于某种原因,plunkr 没有被保存。你能再看看我的plunkr吗?现在我不明白为什么指令本身不呈现(我承认这是我第一次尝试编写一个指令)。另外,知道如何克服“它不存在”的问题吗?再次感谢
  • 另外,我只是尝试自己添加一个 $timeout 但我看不出有什么区别(请随意编辑 Plunkr)
  • 因为你的 main.html 中还有这个 它应该是
  • 是的,我刚刚注意到了。关于超时的任何想法? (如何避免它......就像“等到指令加载”)
  • 嗯,想不出一个干净的方法来做到这一点。我以前从来没有遇到过这个问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-30
  • 1970-01-01
  • 2023-03-13
相关资源
最近更新 更多