我记下这个jsFiddle是为了复制我的场景。我基本上通过ui-router
在我的页面上的<div>
内加载这个视图,以及一个用$state.go
加载它的指令。指令的控制器应该监听一个名为myEvent:<scope.$id>
的事件(在小提琴中它是myEvent:2
,例如),而外部视图应该触发那个事件,因为它加载了适当的$stateParams.scopeId
(可以从各自的$scope.ev
属性中看到)。此外,我正在使用$scope.$emit
,因为我收集,从外部视图具有更高的$scope.$id
这一事实来看,事件应该向上传播并最终到达指令的范围并被捕获,或者我错过了什么?欢呼。
UPDATE:我设法通过添加这个来使它工作:
.controller("MyCtrl", ["$scope", function($scope) {
$scope.$root.$on("myEvent:2", function(e, data) {
$scope.$broadcast("myEvent:2", data);
});
}])
(见小提琴),因为我认为外部视图的scope
可能不是指令的scope
的孩子;相反,它们有一个共同的祖先,当然$rootScope
会做得很好。所以我用$emit
把事件一直拖到$rootScope
,然后用$broadcast
把它往下拉。现在的问题是,我必须硬编码事件名称,这是一个主要的交易破坏者,因为我没有事先了解指令的scope.$id
;是否没有方法使用参数化或基于正则表达式的事件名称,例如:
.controller("MyCtrl", ["$scope", function($scope) {
$scope.$root.$on("myEvent:(d+)", function(e, data) {
$scope.$broadcast("myEvent:" + RegExp.$1, data);
});
}])
?
我明白了。技巧是将视图中的通用事件传递给$emit
,并将适当的$scope.$id
传递给事件数据。在$rootScope
上,提取id
并使用它来形成用于重新传播的适当事件名称。