2016-02-29 76 views
8

在Angular 2中,子組件可以通過構造函數參數注入其父組件。例如:注入與子組件類型相同的父組件

@Component({...}) 
export class ParentComponent { 
    ... 
} 

@Component({...}) 
export class ChildComponent { 
    constructor(private parent: ParentComponent) { } 
    ... 
} 

這個效果很好,只要父母和孩子是不同的類型。

但是,另一個典型的用例是樹結構,其中每個樹節點顯示爲一個單獨的組件。如果每個樹節點組件都可以訪問其父項,我們應該怎麼做?我曾經嘗試這樣做:

@Component({...}) 
export class TreeNodeComponent { 
    constructor(private parent: TreeNodeComponent) { } 
... 
} 

但這種失敗,出現以下運行時異常:

EXCEPTION: Cannot instantiate cyclic dependency! 

我猜原因是角2注入部件本身,而不是它的父組件。

我怎麼能告訴角注入組件的父組件,即使它們是相同類型?

Plunkerhttps://plnkr.co/edit/ddvupV?p=preview

+0

爲什麼要注入父項,爲什麼不直接使用數據綁定? –

+0

試試這個:http://stackoverflow.com/questions/34540615/how-do-i-inject-a-parent-component-into-a-child-component – Damitha

回答

15

這樣,它的工作

constructor(@SkipSelf() @Host() @Optional() parent: TreeNodeComponent) {} 

Plunker

  • @SkipSelf()是不要讓自己注射,如果TreeNodeComponent請求
  • 012將適用
  • @Host()看起來不比主機元件更深
  • @Optional() ??沒有根節點

參見http://blog.thoughtram.io/angular/2015/08/20/host-and-visibility-in-angular-2-dependency-injection.html

+0

她是一個蹲點:[link](https: //plnkr.co/edit/ddvupV?p=preview)。閱讀treenode.component中的評論。 – user928437

+0

我瞭解您對該策略的評論,我完全同意。它會使用綁定,而不是像這樣的樹結構。我的實際使用情況是不同的。我僅以樹節點爲例來說明核心挑戰,因爲樹結構是一個衆所周知的概念。 – user928437

+0

我不能使它工作,也沒有與Thierrys方法。我會考慮這個錯誤。 –

0

Angular2眺望電流注入器的供應商父TreeNodeComponent。在你的情況下,TreeNodeComponent對應於組件本身。

父組件實例位於父注入器中。

我認爲你可以嘗試注入一個Injector類來訪問父注入器,然後獲取父組件的實例。類似的東西:

@Component({ 
    (...) 
}) 
export class TreeNodeComponent { 
    constructor(injector:Injector) { 
    let parentInjector = injector.parent; 
    let parent = patentInjector.get(TreeNodeComponent); 
    } 
} 

請參閱此鏈接注射器類的文檔:

這就是說,我認爲岡特的有關綁定註釋和共享服務特別是相關...

0

這個帖子已經由Günther解決了。不過,我想根據我得到的建築反饋進行跟進。

首先和最重要的是:我完全同意TreeNodeComponent用例是一個反模式。像樹這樣的數據驅動組件應該由數據綁定來控制。我對這種反模式表示歉意。

但是,我的實際使用案例(這是更復雜的解釋)是,我想開發一個先進的下拉菜單。要求:

  • 下拉應該有
  • 下拉被定義在設計時水平的任意數(菜單,子菜單,subsubmenu等) - 其內容不是基於動態數據。
  • 應該可以將事件處理程序(_)=附加到每個下拉項目。
  • 應該可以將自定義控件組件插入到下拉列表中。

的利用方法:

<dropdown label="Actions"> 
    <dropdown-item label="Action 1" (click)="action1()"></dropdown-item> 
    <dropdown-item label="Action 2" (click)="action2()"></dropdown-item> 
    <dropdown-item label="Submenu"> 
    <dropdown-item label="Action 3.1" (click)="action31()"></dropdown-item> 
    <dropdown-item label="Action 3.2"> 
     <dropdown-slider (change)="changeHandler()"></dropdown-slider> 
    </dropdown-item> 
    <dropdown-item label="Submenu"> 
     <dropdown-item label="Action 3.3.1" (click)="action331()"></dropdown-item> 
     <dropdown-item label="Action 3.3.2" (click)="action332()"></dropdown-item> 
    </dropdown-item> 
    </dropdown-item> 
</dropdown>  

我考慮的是,這將是很難使用數據綁定來實現。能夠以這種方式綁定事件處理程序幷包含自定義組件是非常實用的。

但我可能是錯的!任何意見都非常歡迎!

+0

這看起來不像一個答案。我認爲最好是編輯你的問題,並在那裏添加這個內容。 –

+0

你爲什麼要注射父母?您想從父母訪問哪些成員? –

+0

我需要注入父項,因爲打開一個菜單項應該關閉所有的同胞,以便同時打開一個「菜單路徑」。爲了實現這一點,我必須能夠調用父組件。 – user928437