播出指令未收到 [英] Broadcast not received in directive

查看:255
本文介绍了播出指令未收到的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我的℃之间的父子控制的关系;主> < D​​IV> <我的指导性> 这样:

 <主NG控制器=MainController>    <&导航GT;
        < UL>
            <李> 1 LT; /李>
            <李> 2'; /李>
            <立GT;第3版; /李>
            <立GT; 4℃; /李>
        < / UL>
    < / NAV>    < D​​IV NG控制器=AboutController>    < / DIV>    <我的指导性和GT;< /我-指令>< /主>

在MainController,我和一个执行$播报:

  $ $范围广播('shoppingCartReady',味精)。

在AboutController,我可以成功地通过receieve这个$播报:

  angular.module('aboutModule',[])
    .controller('AboutController,要求('./约/ aboutController'));VAR AboutController =功能($范围,$ rootScope){    $范围。在$('shoppingCartReady',函数(事件,味精){
        的console.log(味精);
    });};module.exports ='$范围,$ rootScope',AboutController]

然而,试图在收到$广播时<我的指导性> 链接功能,它似乎永远不会被接收:

  angular.module('shopModule',[])
    .directive('shopModuleDirective,要求('./ shopModuleDirective'))
    .directive('myDirective,要求('./ myDirective'));VAR myDirective =功能($ rootScope){    功能链接($范围,元素,ATTRS,baseCtrl){        $范围。在$('shoppingCartReady',函数(事件,味精){
            的console.log(味精);
        });
    }    返回{
        限制:'E',
        要求:'^ shopModuleDirective',
        链接:链接
    };
};返回['$ rootScope',myDirective]

更新


我甚至我的指令中创建控制器:

  angular.module('shopModule',[])
    .directive('shopModuleDirective,要求('./ shopModuleDirective'))
    .directive('myDirective,要求('./ myDirective'));VAR myDirective =功能($ rootScope){    VAR控制器=$范围,$元素,功能($范围,元素){
        的console.log('等。对...');
        $范围。在$('shoppingCartReady',函数(事件,缓存){
             的console.log('shoppingCartReady。对RCVD!');
        });
    }]    功能链接($范围,元素,ATTRS,baseCtrl){        $范围。在$('shoppingCartReady',函数(事件,味精){
            的console.log(味精);
        });
    }    返回{
        限制:'E',
        要求:'^ shopModuleDirective',
        链接:链接
    };
};返回['$ rootScope',myDirective]

我可以看到日志

 的console.log('等。对...');

不过。对被从未收到。

更新:


我觉得可能的原因是由于示波器的不是'准备好'。

在我原来的广播从MainController,如果我在的setTime 出来,所有的<$ C $后再进行一次C>。对接收

MainController:

  $ $范围广播('shoppingCartReady',味精)。的setTimeout(函数(){
    。$ $范围广播('shoppingCartReady',味精);
},8000);


解决方案

有一个竞争条件。

myDirective 控制器和链接后功能的后 MainController 执行,听者后<$成立C $ C> shoppingCartReady 事件被触发。

经验为好,可测试指令设计的原则是保持所有范围相关的逻辑控制器,连接功能和 $的OnInit 挂钩是否完全用于事应该发生存在,而不是其他地方,像编译DOM内容的操作。

不太明显,但独特的用例链接是执行理想的顺序(后联函数以相反的顺序执行的,从儿童到父母)。如果 MainController 成为一个指令,而范围。$广播('shoppingCartReady',味精)在<$ C所执行$ C>链接功能,而不是控制,这保证执行的正确顺序。

包装控制器code到零 $超时也将推迟code

  $超时(函数(){
    。$ $范围广播('shoppingCartReady',味精);
});

小儿指令功能连接后执行,但也将指定一些code气味。这就是为什么范围事件指令沟通不太理想的方式,而且容易被反模式的原因之一。

处理这种替代方式取决于 shoppingCartReady 事件是什么,但是在目前的情况下,它是多余的:它已经在此刻发生了儿童控制器执行时,他们可以安全地假定购物车已准备就绪。

建议阅读这个主题:指令控制器和链路时序在AngularJS

I have a parent-child controller relationship between my <main>, <div> and <my-directive> as such:

<main ng-controller="MainController">

    <nav>
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
    </nav>

    <div ng-controller="AboutController">

    </div>

    <my-directive></my-directive>

</main>

Within the MainController, i perform a $broadcast with a:

$scope.$broadcast('shoppingCartReady', msg);

Within AboutController, i can successfully receieve this $broadcast via:

angular.module('aboutModule', [])
    .controller('AboutController', require('./about/aboutController'));

var AboutController = function ($scope, $rootScope) {

    $scope.$on('shoppingCartReady', function(event, msg){
        console.log(msg);
    });

};

module.exports = [ '$scope', '$rootScope', AboutController];

However, when trying to receive the $broadcast within <my-directive> link function, it seems to never be received:

angular.module('shopModule', [])
    .directive('shopModuleDirective', require('./shopModuleDirective'))
    .directive('myDirective', require('./myDirective'));

var myDirective = function ($rootScope) {

    function link($scope, element, attrs, baseCtrl) {

        $scope.$on('shoppingCartReady', function (event, msg) {
            console.log(msg);
        });
    }

    return {
        restrict: 'E',
        require: '^shopModuleDirective',
        link: link
    };
};

return ['$rootScope', myDirective];

UPDATE


I have even created a controller within my directive:

angular.module('shopModule', [])
    .directive('shopModuleDirective', require('./shopModuleDirective'))
    .directive('myDirective', require('./myDirective'));

var myDirective = function ($rootScope) {

    var controller = ["$scope", "$element", function ($scope, element) {
        console.log('waiting for .on....');
        $scope.$on('shoppingCartReady', function (event, cache) {
             console.log('shoppingCartReady .on rcvd!');
        });
    }]

    function link($scope, element, attrs, baseCtrl) {

        $scope.$on('shoppingCartReady', function (event, msg) {
            console.log(msg);
        });
    }

    return {
        restrict: 'E',
        require: '^shopModuleDirective',
        link: link
    };
};

return ['$rootScope', myDirective];

I can see the log for

console.log('waiting for .on....');

But the .on is never received.

UPDATE:


I think the possible cause is due to scope's not being 'ready'.

Within my original broadcast from MainController, if i perform another after a setTime out, all .on are received:

MainController:

$scope.$broadcast('shoppingCartReady', msg);

setTimeout(function(){
    $scope.$broadcast('shoppingCartReady', msg);
}, 8000);

解决方案

There is a race condition.

myDirective controller and post-link function are executed after MainController, and the listener is set up after shoppingCartReady event has been triggered.

A rule of thumb for good, testable directive design is to keep all scope-related logic in controller, linking functions and $onInit hook are used exactly for the things that should happen there and not anywhere else, like manipulations on compiled DOM content.

Less obvious but distinctive use case for link is the desirable order of execution (post-linking functions are executed in reverse order, from children to parent). If MainController becomes a directive, and scope.$broadcast('shoppingCartReady', msg) is executed in link function and not controller, this guarantees the proper order of execution.

Wrapping controller code into zero $timeout will also postpone the code

$timeout(function(){
    $scope.$broadcast('shoppingCartReady', msg);
});

to be executed after linking functions in children directives, but will also designate some code smell. This is one of the reasons why scope events are less desirable ways of directive communication and are prone to be anti-patterns.

The alternative way of handling this depends on what shoppingCartReady event is about, but in current case it is redundant: it has already happened at the moment when children controllers are executed, they can safely assume that 'shopping cart is ready'.

A suggested reading for this topic: Directive Controller And Link Timing In AngularJS .

这篇关于播出指令未收到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆