我有一个父子关系控制器之间的我<main>
,<div>
并<my-directive>
为这样的:
<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>
在MainController中,我使用以下命令执行$ broadcast:
$scope.$broadcast('shoppingCartReady', msg);
在AboutController中,我可以通过以下方式成功接收此$ broadcast:
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];
但是,当尝试在<my-directive>
链接函数中接收$ broadcast时,似乎永远不会收到它:
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];
更新
我什至在指令中创建了一个控制器:
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];
我可以看到有关的日志
console.log('waiting for .on....');
但是.on从未收到。
更新:
我认为可能的原因是由于示波器尚未“就绪”。
在我broadcast
从MainController发来的原始邮件中,如果我在setTime
出局后再执行另一遍,则会.on
收到所有消息:
主控制器:
$scope.$broadcast('shoppingCartReady', msg);
setTimeout(function(){
$scope.$broadcast('shoppingCartReady', msg);
}, 8000);
有比赛条件。
myDirective
控制器和后链接功能在之后执行MainController
,并在shoppingCartReady
事件触发后设置侦听器。
良好的,可测试的指令设计的经验法则是将所有与范围相关的逻辑保留在控制器中,链接函数和$onInit
钩子完全用于应该在此处而不是在其他任何地方发生的事情,例如对已编译DOM内容的操作。
不太明显但与众不同的用例link
是所需的执行顺序(后链接功能以相反的顺序执行,从子级到父级)。如果MainController
成为指令,并且scope.$broadcast('shoppingCartReady', msg)
在link
函数而不是控制器中执行,则可以保证正确的执行顺序。
将控制器代码包装为零$timeout
也会延迟代码
$timeout(function(){
$scope.$broadcast('shoppingCartReady', msg);
});
在链接儿童指令中的函数后执行,但也会指定一些代码味道。这是范围事件不是指令通信的理想方式并且容易成为反模式的原因之一。
处理此shoppingCartReady
事件的另一种方法取决于发生什么事件,但是在当前情况下是多余的:在执行子级控制器的那一刻已经发生了这种情况,他们可以安全地假定“购物车已准备就绪”。
关于该主题的建议阅读:AngularJS中的指令控制器和链接时序。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句