Angular 2+/4/5/6/7:智能、愚蠢和深度嵌套的组件通信 [英] Angular 2+/4/5/6/7: Smart, dumb and deeply nested component communication

查看:24
本文介绍了Angular 2+/4/5/6/7:智能、愚蠢和深度嵌套的组件通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:为简单起见,将组件深度视为:

NOTE: for simplicity consider the component depths as:

- Smart (grand)parent level 0
  - dumb child level 1
   ....
    - dumb grandchild level 2
      ....)

关于智能/大/父/子组件如何在 MULTI-LEVEL(至少 3 个级别)链上进行通信和向上和向下传递数据,有多种选项和条件.我们希望将我们的智能"(大)父组件作为唯一可以访问我们的数据服务(或原子/不可变存储)的组件,它将推动与哑"(大)子组件的信息交换.我们看到的选项是:

There are various options and conditions on how smart/grand/parent/child components communicate and pass data up and down a MULTI-LEVEL (at least 3 levels) chain. We'd like to keep our 'smart' (grand)parent component as the only component that has access to our data service (or atomic/immutable store) and it will drive exchange of information with 'dumb' (grand)children. The options we see are:

  1. Anti-pattern(?):通过@Input/@Output 绑定在组件链上向下和向上传递数据.这就是一些人所说的无关属性"或自定义事件冒泡问题"(例如:这里此处.).不行.
  2. 反模式:智能组件通过@ViewChildren 或@ContentChilden 访问哑(孙)子.这再次硬连线了子级,但仍然没有为(孙)子级创建一个干净的机制来将数据向上传递给智能组件.
  3. angular.io 说明书中描述的共享消息服务 这里 和一篇优秀的帖子此处.
  4. ?
  1. Anti-pattern(?): Pass data down and up the component chain via @Input/@Output bindings. This is what some refer to as the 'extraneous properties' or 'custom event bubbling problem' (eg: here and here.). No go.
  2. Anti-pattern: Smart component access to dumb (grand)children via @ViewChildren or @ContentChilden. This again hardwires the children and still doesn't create a clean mechanism for the (grand)children to pass data UP to the smart component.
  3. Shared message service as described in the angular.io cookbook here and an excellent post here.
  4. ?

现在在'3'的情况下,哑(孙)子必须注入消息服务.这让我想到了我的问题:

Now in case of '3', the dumb (grand)children must have the message service injected. Which brings me to my questions:

Q1:对于每个哑巴"(孙)孩子来说,注入消息服务似乎很奇怪.消息服务的最佳实践是为这个家庭提供专门的服务,还是依赖上述聪明"祖父母负责的数据服务?

Q1: It seems intuitively odd for each of the 'dumb' (grand)children to have a message service injected. Is best practice for the message service to be a dedicated service for this family OR does it piggy back on the data service the 'smart' grandparent is charged with mentioned above?

Q1A:此外,如果所有组件都将注入服务,这比在链上添加@Input/@Output 绑定有什么好处?(我看到哑"组件需要某种方式来获取信息的论点)

Q1A: Additionally, how is this much better than adding @Input/@Output bindings up and down the chain if all the components will have a service injected? (I see the argument that the 'dumb' component needs SOME way to get info)

Q2:如果聪明的"祖父母正在与类似 redux 的商店(我们的 ngrx)进行通信怎么办?再一次,与哑"组件的通信最好通过注入/专用消息服务发生,还是最好将存储注入每个哑"组件......或者?请注意,组件间通信是操作"(例如:表单验证、禁用按钮等)以及数据(即向/更新存储或服务添加数据)的组合.

Q2: What if the 'smart' grand parent were communicating with a redux-like store (ngrx for us)? Once again is the communication with the 'dumb' components best happen via an injected/dedicated messages service or is it best to inject the store into each 'dumb' component...or? Note, the inter-component communication is a combination of 'actions' (eg: form validation, disable button, etc) in addition to data (i.e. add data to/update store or service).

非常感谢您的想法!

推荐答案

(更新:02-07-2019:这篇文章已经过时——添加了store/ngrx"模式)

(UPDATE: 02-07-2019: This post was getting dated--added the 'store/ngrx' pattern)

所以在进一步研究之后,当谈到如何最好地向下和向上通信嵌套组件链时,似乎只有两种选择——两者之间的浮士德式讨价还价:

So after looking into this further, when it comes to how best to communicate down and up a nested component chain, there seems to be really only two options -- a Faustian bargain between:

要么

  • 要么在嵌套组件链中向上、向下传递@Input/@Output 绑定(即处理'自定义事件冒泡' 或'无关属性' 的问题)

  • 使用消息/订阅服务在这一系列组件之间进行通信(很好的描述 此处) 并为链中的每个组件注入该服务.
  • Use a messaging/subscription service to communicate between this family of components (great description here) and inject that service for each component in the chain.

或:

  • 反应式存储模式(例如'ngrx')是另一种选择.请注意,IMO,智能和哑组件的概念仍然适用.也就是说,哑组件永远不会直接访问存储.同样,智能组件是通过商店获取数据的主要方.

我个人是使用智能和展示(愚蠢")组件的支持者.添加商店"也应该有选择地进行,因为它会显着增加从架构、一致的实施模式、开发和维护到新人员入职的流程成本.名义上,哑"组件只需要@Inputs 和@Outputs,仅此而已.它并不关心它在组件树中的深度或浅度——这是应用程序的问题.事实上,它并不关心什么应用程序首先使用它.同时,如果将特定于应用程序的服务注入其中,那么深层组件就不是非常笨拙或可移植的.顺便说一句,对应的智能"组件实际上是为其家谱中需要它的任何愚蠢组件提供中间服务(通过一流的@Injectable 服务或类似 redux 的商店).只要孙子以某种方式发出需要采取服务/存储操作的信号(再次通过@Input/@Output 链),智能组件也不关心其直接子级@Inputs 之外的组件.通过这种方式,智能组件也可以跨应用程序线传输.

I'm personally a proponent of utilizing smart and presentational ('dumb') components. Adding a 'store' should also be done selectively as it significantly increases the costs of the process ranging from architecture, consistent implementation patterns, development, and maintenance to on-boarding of new personnel. Nominally, a 'dumb' component only needs @Inputs and @Outputs and that's it. It does not care how deep or shallow it is in a component tree--that's the applications problem. In fact it doesn't care what application uses it in the first place. Meanwhile, a deep down component isn't very dumb or transportable if an application specific service is injected into it. BTW, the counter-part 'smart' component is really providing intermediary services (via a first class @Injectable service or redux-like store) to whichever dumb component in its family tree that needs it. The smart component also doesn't care about components beyond its immediate child's @Inputs as long as the grandchildren somehow signal up a service/store action needs to be taken (again via the @Input/@Output chain). This way a smart component also becomes transportable across application lines.

鉴于此,浮士德式的交易,IMO,倾向于使用@Input/@Output 链以及它带来的所有提到的问题.也就是说,我一直在关注这一点,如果有人知道的话,欢迎使用干净且分离的替代方案.

Given this, the Faustian bargain, IMO, leans towards utilizing an @Input/@Output chain with all the mentioned issues it brings with it. That said, I'm keeping an eye on this and welcome clean and decoupled alternatives if anyone knows of any.

这篇关于Angular 2+/4/5/6/7:智能、愚蠢和深度嵌套的组件通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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