组件通信

本文介绍的内容是组件通信的常用方式:@Input、@Output、@ViewChild、模板变量、MessageService、Broadcaster (Angular 1.x $rootScope 中 $on、$broadcast ) 和 Pub - Sub 模式、RxJS Subject 存在的问题。

输入属性 (父组件 -> 子组件)

counter.component.ts

------ - ---------- ----- - ---- ----------------

------------
    --------- --------------
    --------- -
      ------- -- ----- ------
      ------- ---------------------- - ---------
      ------- ---------------------- - ---------
    -
--
------ ----- ---------------- -
    -------- ------ ------ - --

    ----------- -
        -------------
    -

    ----------- -
        -------------
    -
-

app.component.ts

------ - --------- - ---- ----------------

------------
  --------- ----------
  --------- -
   ------------ ------------------------
  -
--
------ ----- ------------ -
  ------------- ------ - --
-

输出属性 (子组件 -> 父组件)

counter.component.ts

------ - ---------- ------ ------- ------------ - ---- ----------------

------------
    --------- --------------
    --------- -
      ------- -- ----- ------
      ------- ---------------------- - ---------
      ------- ---------------------- - ---------
    -
--
------ ----- ---------------- -
    -------- ------ ------ - --

    --------- ------- -------------------- - --- -----------------------

    ----------- -
        -------------
        -----------------------------
    -

    ----------- -
        -------------
        -----------------------------
    -
-

app.component.ts

------ - --------- - ---- ----------------

------------
  --------- ----------
  --------- -
   -------------------- 
   ------------ ---------------------- --------------------------------
  -
--
------ ----- ------------ -
  ------------- ------ - --

  ---------- -------

  ------------------ ------- -
    -------------- - --------------------- ----------
  -
-

模板变量

child.component.ts

------ ----------- ---- ----------------

------------
  --------- ------------------
  --------- ---- -- ---- ---
--

------ ----- -------------- -
  ------ ----- -------
-

parent.component.ts

------ ----------- ------- ---- ----------------
------ ---------------- ---- -----------------------

------------
  --------- -------------------
  --------- -
    ---------------- -----------
    ------- ------------------- - ---------------------------
  -
--

------ ----- --------------- ---------- ------ -

  ------- ---------- -------

  ------------- - -

  ---------- - 
    -------------- - ------------------
  -
-

@ViewChild 装饰器

child.component.ts

------ - ---------- ------ - ---- ----------------

------------
    --------- ------------
    --------- -
      -------- -------------  
    -
--
------ ----- -------------- -
    ----- ------ - ---
-

app.component.ts

------ - ---------- ---------- ------------- - ---- ----------------
------ - -------------- - ---- --------------------

------------
  --------- ---------
  --------- -
    ----------- -- ------- ----------
    ------------
  --
--
------ ----- ------------ -

  --------------------------
  --------- ---------------

  ----------------- -
    ------------------ - ------------------
  -
-

使用 MessageService - 基于 RxJS Subject

message.service.ts

------ - ---------- - ---- ----------------
------ ------------ ---- ------------------
------ - ------- - ---- ---------------

-------------
------ ----- -------------- -
    ------- ------- - --- ---------------

    -------------------- ------- -
        ------------------- ----- ------- ---
    -

    -------------- -
        --------------------
    -

    ------------- --------------- -
        ------ ----------------------------
    -
-

home.component.ts

------ - --------- - ---- ----------------
------ - -------------- - ---- --------------------

------------
    --------- -----------
    --------- -
    -----
        -------------
        ------- ---------------------------- ----------------
        ------- ------------------------------ ----------------
    -------
--

------ ----- ------------- -
    ------------------- --------------- --------------- --

    -------------- ---- -
        ---------------------------------------- ---- ---- --------- -- --- -------------
    -

    --------------- ---- -
        -----------------------------------
    -
-

app.component.ts

------ - ---------- --------- - ---- ----------------
------ - ------------ - ---- --------------------
------ - -------------- - ---- --------------------

------------
    --------- ---------
    --------- -
    -----
       ---- --------------------------------------
       -----------
    ------
    -
--

------ ----- ------------ ---------- --------- -
    -------- ----
    ------------- -------------

    ------------------- --------------- --------------- -
        ----------------- - -------------------
                                ------------------------ ------- -- - 
                                    ------------ - -------- 
                                 ---
    -

    ------------- -
        --------------------------------
    -
-

使用 Broadcaster - 基于 RxJS Subject

实现 Angular 1.x 中的 $rootScope 对象中 $on$broadcast 的功能。

broadcaster.ts

------ - ---------- - ---- ----------------
------ --------- ---- ---------------
------ ------------ ---- ------------------
------ ---------------------------
------ ------------------------

--------- -------------- -
  ---- ----
  ------ ----
-

-------------
------ ----- ----------- -
  ------- ---------- ------------------------

  ------------- -
    -------------- - --- --------------------------
  -

  -------------- ---- ------ ---- -
    ------------------------- -------
  -

  ---------- ----- ------------- -
    ------ -----------------------------
      ------------- -- --------- --- ----
      ---------- -- ---------------
  -
-

child.component.ts

------ - --------- - ---- ----------------

------------
    --------- -------
--
------ ----- -------------- -
  ------------------- ------------ ------------ --

  ------------------------- -
    --------------------------------------
      ------------------ -- -
        ---
      ---
  -

  --------------------- -
    ------------------------------------- ----- ----------
  -
-

本文主要是介绍组件通讯的思路,提供的都是相对简单的示例。如果想深入了解,请参考 - angular.cn - component-communication

我有话说

1.在实际开发中,我们也经常使用 Pub (发布) - Sub (订阅模式) 来实现模块之间的消息通讯。接下来我们看一下 Pub - Sub 的核心点:

  • 至少包含 subscribe() 和 publish() 两个方法,subscribe() 用于实现消息订阅,publish() 方法用于发布消息。
  • 支持订阅不同的消息类型,且对于任何一种消息类型都可以添加多个观察者。内部实现一般使用 key-value 结构进行消息类型和观察者列表的存储。
  • 订阅观察者后,最好返回一个对象或函数对象,用于取消订阅。

具体示例如下(详细信息,请参考 - [Pub/Sub JavaScript Object](Pub/Sub JavaScript Object)):

--- ------ - ------------
  --- ------ - ---
  --- --- - ----------------------

  ------ -
    ---------- --------------- --------- -
      -- ----------------
      -------------------- ------- ------------- - ---

      -- ----------
      --- ----- - ---------------------------- ---

      -- ----------------
      ------ -
        ------- ---------- -
          ------ ---------------------
        -
      --
    --
    -------- --------------- ----- -
      -------------------- ------- -------

      ------------------------------------ -
            --------- -- --------- - ---- - ----
      ---
    -
  --
-----

使用示例:

--- ------------ - ------------------------------ ------------- -
    -- ----
---

---------------------------- -
    ---- ---------------- 
---

2.RxJS Subject 在使用中存在一个问题,就是如果某个 observer (观察者) 在执行的时候出现异常,却没有进行异常处理,那么就会影响到其它的观察者。解决该问题,最简单的方式就是为所有的观察者添加异常处理。具体问题如下:

----- ------ - -----------------------------
----- ------- - --- -------------

----- ------- - ------------- -- -
    -- -- --- -- -
        ----- --- --------------
    -
    ------ --
---
------------------- -- ---------------- ----
------------------- -- ---------------- ----
------------------- -- ---------------- ----

--------------------------

以上代码运行后,控制台的输出结果:

- -
- -
- -
- -
------------ -------- ------ ----

解决方案:

----- ------ - -----------------------------
----- ------- - --- -------------

----- ------- - ------------- -- -
    -- -- --- -- -
        ----- --- --------------
    -
    ------ --
---

------------------
    - -- ---------------- ---
    ----- -- -------------- ------- - ------
--

------------------
    - -- ---------------- ---
    ----- -- -------------- ------- - ------
--

------------------
    - -- ---------------- ---
    ----- -- -------------- ------- - ------
--

--------------------------

关于 RxJS Subject 的详细信息,请查看 - RxJS Subject


上一篇:constructor与ngOnInit