2016-02-29 10 views
8

角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

彼女はプランナーです:[リンク](https: //plnkr.co/edit/ddvupV?p=preview)。 treenode.componentのコメントを読んでください。 – user928437

+0

私は戦略についてのあなたのコメントを理解し、私は完全に同意します。このような木構造の場合は、代わりにバインディングを使用していました。私の実際のユースケースは異なります。ツリー構造はよく知られている概念なので、私は単にツリーノードを例として使用してコアの課題を説明しました。 – user928437

+0

私はそれを動作させることができませんでした。ティエリスのアプローチでもできませんでした。私はこれをバグと考えています。 –

0

Angular2は、プロバイダの現在のインジェクタに見えるルートノードには親TreeNodeComponentはありません。あなたの場合、TreeNodeComponentはコンポーネント自体に対応しています。

親コンポーネントインスタンスは、親インジェクタに配置されています。

私は、インジェクタークラスを注入して親インジェクターにアクセスし、親コンポーネントのインスタンスを取得しようとすると思います。そのような何か:

@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

メニュー項目を開くとすべての兄弟を閉じて、同時に1つの「メニューパス」しか開くことができないため、親を注入する必要があります。これを達成するためには、親コンポーネントを呼び出すことができなければなりません。 – user928437

関連する問題