这可能听起来有点模糊,但我仍在学习并试图了解其工作原理。
我开始使用'侧菜单'启动离子项目,它已经设置了一个urlrouter配置,带有'app'抽象状态/视图/控制器以及一些带有自己控制器的其他状态。
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
.state('app.home', {
url: "/home",
views: {
'menuContent': {
templateUrl: "templates/home.html",
controller: 'HomeCtrl'
}
}
})
.state('app.page2', {
url: "/page2",
views: {
'menuContent': {
templateUrl: "templates/page2.html",
controller: 'Page2Ctrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/app/home');
})
在App Controller(AppCtrl)中,我正在侦听一个名为repeatMyEvent的事件,它会广播一个名为myEvent的事件。
我在myEvent事件的每个其他控制器中都有一个监听器。当我从任何其他控制器发出repeatMyEvent事件时(我在模板上有一个调用testEmit()函数的按钮),我只看到发出repeatMyEvent事件的控制器响应myEvent事件。似乎也许只有控制器的视图当前可见才响应它。但是,我希望所有控制器都能响应它。
angular.module('starter.controllers', [])
.controller('AppCtrl', function($scope, $ionicModal, $timeout) {
// Form data for the login modal
$scope.$on('repeatMyEvent', function(event, args) {
console.log('repeatMyEvent event received');
$scope.$broadcast('myEvent');
});
})
.controller('HomeCtrl', function($scope, $stateParams) {
$scope.$on('myEvent', function(event, args) {
console.log('HomeCtrl received myEvent');
});
$scope.testEmit = function() {
$scope.$emit('repeatMyEvent');
}
})
.controller('Page2Ctrl', function($scope, $stateParams) {
$scope.$on('myEvent', function(event, args) {
console.log('Page2Ctrl received myEvent');
});
$scope.testEmit = function() {
$scope.$emit('repeatMyEvent');
}
})
;
我能理解这一点的唯一方法是抽象状态的控制器不是单例,我的每个控制器都有自己的版本。或者我是否完全误解了$ scope应该如何与控制器相关?
所有这些的后续操作是如何使其工作,以便所有控制器响应来自AppCtrl的广播消息。
注意:我也尝试过$ scope。$ root,我也有同样的行为。
答案 0 :(得分:0)
控制器被实例化,$ scope DI'd => link (不是单身人士);
从我在路由器中看到的内容,您有三个单独的页面,每个页面都有自己的URL。我很好奇你为什么要在你的特定DOM甚至没有呈现时让你的控制器进行交谈。
如果在加载时必须为每个页面维护某种类型的数据对象,则可以创建在初始应用程序加载时运行并包含您的值的工厂/服务。然后只需DI进入需要该服务数据的每个控制器。
此外,这是广播和发射工作的方式。
3
--------
| |
--- ----
1 | 2 |
--- --- --- ---
| | | | | | | |
查看此树。你如何回答以下问题? 注意:还有其他方法,但在这里我们将讨论广播和发射。 此外,当阅读下面的文本时,假设每个数字都有自己的文件(指令,控制器)e.x. one.js,two.js,three.js。
在文件one.js
中scope.$emit('messageOne', someValue(s));
在文件three.js
中scope.$on('messageOne', someValue(s));
在文件two.js
中scope.$emit('messageTwo', someValue(s));
在文件three.js
中scope.$on('messageTwo', someValue(s));
在文件three.js
中scope.$broadcast('messageThree', someValue(s));
在文件one.js&& two.js 您要捕获消息的文件 。
scope.$on('messageThree', someValue(s));
在文件two.js
中scope.$emit('messageTwo', someValue(s));
在文件three.js
中scope.$on('messageTwo', function( event, data ){
scope.$broadcast( 'messageTwo', data );
});
在文件one.js
中scope.$on('messageTwo', someValue(s));
<强>无论其强>
当你让所有这些嵌套的子节点试图像这样进行通信时,你会很快看到许多$ on的$ broadcast和$ emit的。这就是我喜欢做的事情。
在PARENT NODE (本例中为三个......)
所以,在文件three.js
中scope.$on('pushChangesToAllNodes', function( event, message ){
scope.$broadcast( message.name, message.data );
});
现在,在任何子节点中,您只需 $ emit 消息或使用 $ on 捕获消息。
注意:通常很容易在一个嵌套路径中串口而不使用$ emit,$ broadcast或$ on,这意味着大多数用例都适用于您尝试获取< strong> 1 与 2 进行通信,反之亦然。
在文件two.js
中scope.$emit('pushChangesToAllNodes', sendNewChanges());
function sendNewChanges(){
return { name: 'talkToOne', data: [1,2,3] };
}
在文件three.js
中We already handled this one remember?
在文件one.js
中scope.$on('talkToOne', function( event, arrayOfNumbers ){
arrayOfNumbers.forEach(function(number){
console.log(number);
});
});
您仍然需要对要捕获的每个特定值使用$ on,但现在您可以在任何节点中创建任何您喜欢的内容,而无需担心如何在父级差距中获取消息强>
希望这会有所帮助......
答案 1 :(得分:0)
我无法解决具体的沟通问题,因为正如@Wawy在我原帖中的评论所指出的那样,
设置状态配置的方式,只有一个控制器 同时活跃。因为您要用new替换视图 每次页面更改时的内容。
因此,为了处理我的具体问题(这是为了让一个控制器告诉另一个控制器刷新其数据),我只是重新组织了我的代码,将数据刷新功能放在AppCtrl中,然后每个其他控制器都可以发出一个事件告诉它执行数据刷新。