2017-05-07 83 views
15

注意:爲了簡單起見,考慮部件的深度爲:角2 +/4/5:智能,啞和深深嵌套組件通信

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

有多種方案和條件如何智能/隆重/父/子組件在多層(至少3層)鏈上進行通信並傳遞數據。我們希望保留我們的'聰明'(大)父母組件作爲唯一可以訪問我們的數據服務(或原子/不可變的商店)的組件,它將促進與'愚蠢'(大)孩子交換信息。我們看到的選項是:

  1. 反模式(?):通過@ Input/@輸出綁定將數據傳遞給組件鏈。這就是有些人稱之爲「無關屬性」或「自定義事件冒泡問題」的問題(例如:herehere。)問題。不行。
  2. 反模式:智能組件通過@ViewChildren或@ContentChilden訪問啞(大)孩子。這再次硬化了孩子們,並且仍然沒有爲(大)孩子們創建一個乾淨的機制來將數據傳遞給智能組件。
  3. 共享消息服務描述在angular.io食譜here和一個很好的帖子here

現在在'3'的情況下,啞(大)孩子必須注入消息服務。這使我想到了我的問題:

問題1:對於每個'愚蠢'(大)孩子來說,注入消息服務似乎很奇怪。對於消息服務來說,最好的做法是爲這個家庭提供一個專門的服務,還是在上面提到的'智能'祖父母的數據服務上捎帶? Q1A:另外,如果所有組件都會注入一個服務,如何比添加@ Input/@ Output綁定更好? (我看到「愚蠢的」組件需要某種方式來獲取信息的觀點)

Q2:如果'聰明'祖父母正在與一個類似redux的商店(我們的ngrx)進行通信怎麼辦?最好通過注入/專用消息服務與「啞」組件進行通信,或者最好是將商店注入每個「啞」組件......或者,注意,除了數據(即將數據添加到/更新存儲或服務)之外,組件間通信是「動作」(例如:表單驗證,禁用按鈕等)的組合。

非常感謝!

回答

7

尋找這個進一步,當它涉及到如何最好地向下一個嵌套的組件鏈溝通和高達所以以後,似乎真的只有兩種選擇 - 之間的浮士德式的交易:

  • 要麼通@輸入/輸出@綁定向上,向下,並在整個嵌套組件鏈(即處理的「定製事件冒泡」的問題或「外來屬性」)

OR

  • 使用消息傳遞/訂閱服務在此係列組件(很好的說明here)之間進行通信併爲鏈中的每個組件注入該服務。

我個人是利用智能和表現('愚蠢')組件的支持者。名義上,一個「愚蠢的」組件只需要@Inputs和@Outputs就是這樣。它並不關心組件樹的深度或淺度 - 這是應用程序問題。事實上,它並不關心應用程序首先使用它。同時,如果嚮應用程序注入特定服務,深層組件不是非常笨拙或不可移植。順便說一句,對手'聰明'組件真的是提供中介服務(通過第一類@Injectable服務或類似存儲)到其需要它的家族樹中的任何啞組件。只要孫子們以某種方式發出需要採取的服務行爲(再次通過@ Input/@輸出鏈),智能組件也不關心其直接孩子的@Inputs之外的組件。這樣一個智能組件也可以跨應用程序線傳輸。

鑑於此,Faustian的討價還價IMO傾向於利用@ Input/@ Output鏈來解決所帶來的所有問題。也就是說,如果有人知道任何情況,我會密切注意這一點,並歡迎提供乾淨和分離的替代方案。

0

爲什麼#1是反模式?祖父母組件擁有數據並通過@Input參數將其傳遞給啞子組件。當一個事件發生時(通過@Output事件發射器),啞元子組件簡單地調用回調,導致祖父母組件操縱數據。看起來很乾淨。

編輯:我看到你關於通過許多中間層重複傳遞值提交處理程序的觀點。也許可以在父組件中創建代表組件樹的嵌套結構。然後,每個組件可以傳遞它所需的屬性,再加上一個對象傳遞給下一個組件。然後每個組件只知道它下面的一個:

// Parent component builds this object (or gets a service to do it) 

viewModelForChildComponent: { 

    property1NeededForChildComponent, 

    property2NeededForChildComponent, 

    viewModelForGrandChildComponent: { 
     property1NeededForGrandChildComponent, 

     property2NeededForGrandChildComponent, 

     viewModelForGrandGrandChildComponent: { 
      property1NeededForGrandGrandChildComponent, 

      submitHandlerNeededForGrandGrandChildComponent 
     } 
    } 
} 
+0

感謝您的想法。請注意,再次就解耦問題而言,海事組織除了提供間接服務是其主要職責之外,頂級部門不應該真正關心或瞭解其孫輩。順便說一句,這與我原來的問題中的選項'2'沒有太大差別。 – MoMo

+0

不客氣。我想我明白你的意思了 - 頂層父組件現在不僅需要知道子組件需要什麼,而且還需要知道其確切的層次結構。我個人對此表示贊同,因爲我將這種協調視爲父組件的工作。或者我創建一個服務將JSON轉換爲包含表示數據/回調(適用於單元測試)的分層視圖模型。你是對的,這有點像你的第二選擇,但沒有真正觸摸視圖的孩子。無論如何,我很好奇你怎麼最終解決這個問題。祝你好運! –

0

Input()和Output()綁定也是處理這種情況的完全合法的方式。讓智能組件處理生成值的邏輯,然後使用Input()和Output()簡單地傳遞和接收組件鏈上的值。

當然,這指出了智能/視圖方法的缺點之一:更多的文件;更多的樣板。這就是爲什麼我不會爭辯一種適合所有人的單一方法。相反,選擇一種在當前環境中有意義的方法(針對應用程序和組織)。

+0

我已經添加了爲什麼最好解耦嵌套組件鏈中的屬性綁定的鏈接。但是很明顯,如果有一個提交/清除按鈕組件嵌套4層,其整個存在的理由是發出「提交」,爲什麼中間組件需要知道或關心其他問題?我同意普遍認爲這是一種反模式。但是,如果水平深度只有1,那麼我不會看到通過@ Input/@ Outputs傳遞數據的問題。 – MoMo

+0

編輯我的答案,以擴大專家委員會討論多一點,並解決您提出的問題。 – Muirik