我正在阅读有关控制器和指令之间通信的所有答案,但在我看来似乎是使用共享服务并将其注入其中的每一个。当我开发一个非常大规模的应用程序时,我不知道我的页面会包含哪些内容。我可能有2个控制器需要在它们之间进行通信,而且我也可能在同一页面中有5个指令和2个控制器。我从头开始不知道我的视图/页面中会有什么内容,因此我需要一种更好的方法来如何在它们之间进行通信。我正在寻找更好的方法,正确的AngularJS方式。
http://i60.tinypic.com/2z87q05.png
以上是我的观点示例我正在处理:在左侧我有一个指示树,在右侧我有图表控制器和指令网格。我可能有更多,但这是我可能拥有的一个很好的例子。请记住,视图可以包含X个组件,您从一开始就不知道其中的内容。
现在,让我们说每次在左侧的树中选择节点时,我希望能够告诉其他控制器nodeSelectedChange事件发生。我不想给他们每个人注入一个包含该信息的服务,所以我想到了一个类似于所有视图之父的页面管理器控制器。我的页面中的所有控制器/指令都应该只通过PageManagerController相互通信,他是页面中唯一知道他内在的东西的东西。
重要的是要记住:树不知道页面有图表或网格,他们不需要彼此了解才能进行交流。页面管理器知道一切,现在我想让它变得神奇 - 它应该有服务吗?是否每个其他组件都有服务和服务可以与PageManager服务通信?
帮助我思考。希望我可以连接所有的点,以创建一个更好的沟通方式。 我认为sharedService方式适用于小型应用程序,当您从一开始就知道应用程序中发生了什么,但大部分时间 - 您只是不知道谁将何时使用您的指令,它应该能与所有人交谈。
关于活动我不喜欢什么:
我需要一种方法来将指令中的事件NAMES暴露出来,可能是连接到该控制器的服务。
答案 0 :(得分:2)
有几个好的做法:
使用$scope
在运行时依赖项的指令和控制器之间进行通信(例如,从服务器获取的模型,实例化的类等)。要做的就是使用隔离范围,并将属性映射到依赖项:
directive('tree', function(){
return {
scope: {
somevalue : "="
}
}
});
像这样使用:
<tree somevalue="objectFromController">
使用注入服务与静态依赖关系(Presentation Models,全局可共享状态等)进行通信。
directive('tree', function(treeState){
return {
scope: {
somevalue : "="
},
link: function(scope){
// some logic updating the treeState
treeState.openNodes = ['x', 'y'];
}
}
});
controller('ctrl', function($scope, treeState){
// react to treeState changes
// you can use $scope.$watch for it
// or any other way you like
// see: https://github.com/mr-mig/angular-react-to
});
如果您想拥有最大可合成性,请坚持使用第一种模式:
directive('tree', function(){
return {
scope: {
model : "="
},
link: function(scope){
// some logic updating the treeState, stored as scope.model
scope.model.openNodes = ['x', 'y'];
}
}
});
controller('ctrl', function($scope, treeFactory){
$scope.treeModel = treeFactory.create();
// react to treeState changes
// you can use $scope.$watch for it
// or any other way you like
// see: https://github.com/mr-mig/angular-react-to
});
使用模板和绑定作为通信总线来编写这些东西:
<tree model="treeModel">
坚持这种模式,你得到:
答案 1 :(得分:1)
这实际上取决于您希望从树指令共享到页面其他部分的信息类型。
你面前有几个选择:
如上所述,您可以触发事件并监听各种控制器和/或服务中的事件。也就是说,它可以变得非常丑陋,非常快。跟踪事件并确定哪些事件监听器在给定点活跃,可以为最好的工程师提供偏头痛!
另一个选择是使用服务,让我们说一个PageManagerService。在那种情况下,
服务本身将成为共享状态,它将取决于它如何消费和响应状态变化的指令和组件。
但是我越是想到这一点,它就越像是 UI Router 这样的好用例。 UI路由器允许您定义状态,并使页面的不同部分以不同的方式响应状态更改。每个部分都可以通过加载
以自己的方式响应状态变化所以你最终得到的是一个带
的结构树指令中的每个项目都可以是 ui-sref ,这只是一种奇特的方式,而不是重定向到URL,重定向到状态。
然后,您可以在一个地方定义应用程序中的配置,如下所示:
$stateProvider.state('dashboard', {
views: {
"top": { templateUrl: 'my/dashboard.html', controller: 'DashboardCtrl'}
"bottom": { templateUrl: 'my/dashboard-grid.html', controller: 'DashboardGridCtrl'}
}
})
同样,您可以为树指令中的每个项目设置一个状态定义,每个项目只是一个指向不同状态的链接。
当然,状态定义是在AngularJS应用程序的 config 部分完成的,您应该知道它是在应用程序启动之前。如果你还需要动态状态怎么办?
嗯,一些答案/想法也会引导你走下去:
答案 2 :(得分:0)
你可以使用$ on,$ emit和$ broadcast在不同的控制器/范围之间进行通信。
请关注我之前的帖子。我有一个设置插件。你可以试试这个例子。 Angular Js newbie - link in a controller view that triggers another controller action
$on : setup a event handler
$emit : communicate to parent controllers
$broadcast : communicate to child controllers
了解更多访问 - https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope