如何在不使用 SharedService 的情况下在控制器之间进行通信? [英] How to communicate between controllers while not using SharedService between them?

查看:22
本文介绍了如何在不使用 SharedService 的情况下在控制器之间进行通信?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读有关控制器和指令之间通信的所有答案,但在我看来似乎是使用共享服务并将其注入其中的每一个.当我开发一个非常大规模的应用程序时,我不知道我的页面将包含什么.我可能有 2 个控制器需要在它们之间进行通信,我也可能在同一页面中有 5 个指令和 2 个控制器.我从头开始不知道我的视图/页面中会有什么,所以我需要一种更好的方式来在它们之间进行通信.我正在寻找更好的方法,正确的 AngularJS 方法.

I was reading all the answers about communication between controllers and directive, but is seems to me occurred using shared service and inject it to each one of them. When I'm developing a very large scale application, I don't know what my page is going to have in it. I may have 2 controllers need to communicate between them, and I also may have 5 directive and 2 controllers in the same page. I don't know from scratch what is going to be inside my view/page, so I need a better way how to communicate between them. I'm looking for that better way to do it, the right AngularJS way.

http://i60.tinypic.com/2z87q05.png

上面是我正在处理的视图示例:在左侧我有一个指令树,在右侧我有图表控制器和指令网格.我可能拥有的不止这些,但这是我可能拥有的一个很好的例子.请记住,视图可以有 X 个组件,您从一开始就不知道其中包含什么.

Above is my view example I'm working on: on the left side I have a directive tree, on the right side I have chart controller and directive grid. I may have more than this, but this is a good example of what I may have. Keep in mind, the view can have X componenets, you don't know from the beginning what will be in it.

现在,假设每次我在左侧的树中选择节点时,我都希望能够告诉其他控制器 nodeSelectedChange 事件发生了.我不想为他们每个人注入一个保存该信息的服务,所以我想到了一些事情,比如拥有一个页面管理器控制器,它是所有视图的父亲.我的页面中的所有控制器/指令只能通过 PageManagerController 相互通信,他是页面中唯一知道他在里面有什么的东西.

Now, lets say each time I select node in tree on the left, I want to be able to tell the other controllers that nodeSelectedChange event happend. I don't want to inject each one of them a service that holds that info, so I thought about something like having a Page Manager Controller, which is the father of the all view. All my controllers/directives inside my page should talk with each other only by the PageManagerController, he is the only thing in page that knows what he has inside of it.

重要的是要记住:树不知道页面有图表或网格,它们不需要相互了解才能进行通信.页面管理器什么都知道,现在我想让它变魔术——它应该有服务吗?彼此的组件是否应该有服务并且服务可以与 PageManager 服务通话?

Important here to keep in mind: The tree don't know the page has chart or grid, they don't need to know each other in order to communicate. The page manager knows everything, now I want it to make the magic - Should it has a service? Should each other component has service and service can talk with PageManager service?

帮我想想.希望我能把所有的点都连接起来,创造一种更好的交流方式.我认为 sharedService 方式适用于小型应用程序,当您从一开始就知道您的应用程序中发生了什么,但大多数时候 - 您只是不知道谁以及何时将使用您的指令,它应该能够与大家交谈.

Help me to think. Hope I can connect all the dots to create a BETTER way for communication. I think the sharedService way is good for small app, when you know from start what is going on in your app, but most of the time - You just don't know who and when is going to use your directive, it should be able to talk with everyone.

我不喜欢的事件:

  1. 在控制器内部触发的事件,而它应该在服务内部.
  2. 侦听器控制器也应该知道他将要侦听的事件的名称.如果我将事件名称更改为 $emit 或 $broadcast,我需要遍历所有应用程序中的所有侦听器 $on("eventName") 并更改为该唯一名称.
  3. 指令就像一个黑匣子,我不想每次都检查它的内部并找到他正在广播的事件的名称以便与之通信.

我需要一种方法来暴露指令中的事件名称,可能是连接到该控制器的服务.

I need a way to exposed the events NAMES out of the directive, probably with a service connected to that controller.

推荐答案

这实际上取决于您希望从树指令到页面其他部分共享的信息类型.

It really depends on the type of information you want to share from the tree directive to the other sections of the page.

你有几个选择:

正如上面提到的,您可以触发一个事件并侦听各种控制器和/或服务中的事件.也就是说,它会变得非常丑陋,非常快.跟踪事件并找出在给定点处于活动状态的事件侦听器可能会让最优秀的工程师感到头疼!

As someone mentioned above, you could fire an event and listen for events in various controllers and/or services. That said, it can get really ugly, really fast. Tracing events and figuring out what event listeners are active at a given point can give the best engineers a migraine!

另一种选择是使用服务,比如说 PageManagerService.在这种情况下,

Another option would be to use a Service, let's say a PageManagerService. In that case,

  • 每次单击树项都会在 PageManagerService 上设置一些信息,说明它需要显示哪个页面、哪些对象以及哪些项
  • 每个需要更改的组件都可以
    • 注册一个监听器,当 PageManagerService 改变时触发
    • 在服务上添加监视并在 PageManagerService 更改时运行其代码

    服务本身只是共享状态,它会取决于指令和组件如何使用和响应状态变化.

    The service itself is just going to be shared state, and it would be upto the directives and components on how it wants to consume and respond to changes in the state.

    但我越想这个,它就越像是一个很好的用例,比如 UI 路由器.UI Router 允许您定义状态,并让页面的不同部分以不同的方式响应状态变化.每个部分都可以通过加载以自己的方式响应状态变化

    But the more I think about this, the more it seems like a good use case from something like UI Router. UI Router allows you to define states, and have different parts of the page respond in different ways to state changes. Each section could respond to a state change in its own way, by loading

    • 不同的控制器
    • 不同的模板,可能包含不同的组件和小部件

    所以你最终会得到一个结构

    So what you would end up having is a structure with

    • 左侧的 Tree 指令
    • 一个名为 top 的 ui-view
    • 一个名为底部的 ui 视图

    树指令中的每个项目都可以是 ui-sref,这只是一种奇特的说法,而不是重定向到 URL,而是重定向到状态.

    Each item in your tree directive can then be a ui-sref, which is just a fancy way of saying instead of redirecting to a URL, redirect to a state.

    然后,您可以在应用程序中的一个位置定义配置,如下所示:

    You could then define your configurations in your application in a single place, like so:

    $stateProvider.state('dashboard', {
      views: {
        "top": { templateUrl: 'my/dashboard.html', controller: 'DashboardCtrl'}
        "bottom": { templateUrl: 'my/dashboard-grid.html', controller: 'DashboardGridCtrl'}
      }
    })
    

    同样,您可以为树指令中的每个项目定义一个状态,并且每个项目只是指向不同状态的链接.

    Similarly, you could have a state definition for each item in your tree directive, and each one just be a link to a different state.

    当然,状态定义是在 AngularJS 应用程序的 config 部分中完成的,您会知道这是在应用程序启动之前.如果您还需要动态状态怎么办?

    Of course, the state definitions are done in your config section in an AngularJS application, which you would know is before the application starts. What if you needed dynamic states as well?

    好吧,一些答案/想法也可以引导您走下去:

    Well, a few answers / thoughts to lead you down the way for that as well:

    • 必须预定义控制器和服务,您不会动态创建 HTML 内容和/或 JS 控制器
    • 可以在配置部分将 $stateProvider 作为全局变量公开,并在控制器/服务中动态调用 stateProvider.state,无论您有新的状态定义.
    • 但通常情况下,控制器和 HTML 保持不变,我们只需要使用各种参数触发不同的状态.这可以通过调用 transitionTo 函数轻松地完成,以使用各种状态参数转换到定义的状态.
    • The controllers and services would have to be predefined, you would not be dynamically creating HTML content and/or JS controllers
    • It is possible to expose the $stateProvider as a global variable in the config section, and dynamically call stateProvider.state inside a controller / service, wherever you have new state definitions.
    • More often than not though, the controllers and HTML remain constant, and we just need to trigger the different states with various parameters. That can easily be done by calling transitionTo function to transition to a defined state with various state parameters.

    这篇关于如何在不使用 SharedService 的情况下在控制器之间进行通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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