2017-01-03 4 views
0

直接親ではない親コンポーネントを注入する必要があります。角度2の子に上位親コンポーネント(直系の親ではない)を注入

@Host() decoratorは、直接の親コンポーネントのみを注入することができます。

実際の例 - メニューとメニュー項目のコンポーネント。私は

<menu [name]="'smth'"> 
    <auth-logout></auth-logout> 
    <!-- ... other menu items --> 
</menu> 

name入力はメニューサービスを通じてメニュー(e.x.トグル)でアクションを呼び出すページにメニューを配置します。 任意のメニュー項目の子コンポーネントがmenu-itemコンポーネント

<menu-item (itemClick)="logout()"> 
    LOGOUT 
</menu-item> 

menu-itemテンプレート

<div class="menu-item"  
    (click)="onClick()"> 
    <ng-content></ng-content> 
</div> 

plnkr http://plnkr.co/edit/ArQZYZsHQgn6I2eK3AZd

を含むことができ、私はmenu-itemクリックイベントにclose()メソッドを呼び出すことがmenu-itemmenuコンポーネントを注入します。 auth-logoutは、このメニュー - コンポーネントのやりとりについて何も知ってはいけません。それぞれのメニュー項目で論理をクローズする必要はありません。

どうしてそんなに包まないの?

<menu> 
    <menu-item> 
    <auth-logout></auth-logout> 
    </menu-item> 
</menu> 

menu-itemブロックは、子コンポーネント(EXパディング)に適切なクリックを壊し、いくつかのスタイルを持っており、それは、クリックで自動的に閉じ、メニューには難しい(auth-logoutのように各コンポーネントにメニュー名を渡すか、このコンポーネントで出力を追加する必要があるため)

menu-itemからサービスコールを使用しないのはなぜですか? 各メニュー項目(auth-logoutなど)からメニュー名を渡してmenu-itemにする必要があるため、auth-logoutのようなコンポーネントはこの相互作用やメニュー名などについては何も知らないようにしてください。

もう一つの例は、 - いくつかの項目のサブコンポーネントを持つアイテムリスト、変更イベント(リスト成分の被写体)をリストし、EMITにいくつかのものを実行するためにリッスン(EXアイテム画像キャッシュをリセットする新しいタイムスタンプPARAMを添加することによりsrc更新と更新イメージ)。

このケースはng1でrequireというプロパティでうまくいきます。このプロパティでは、上位レベルの親を上位レイヤに挿入することができます。成分

更新:

例は、上記のコンストラクタ注入(THXの@yurzui)でprivateを逃し@Host()を除去し、添加を介して固定することができます。 しかし、実際の問題はより複雑で、この解決策は役に立ちません。ここにplnkrが更新されました。 http://plnkr.co/edit/p7Vd4FRpHPRtyEuL6pEZ

差がmenu-itemコンポーネントにこのテンプレート

<menu> 
    <ng-content></ng-content> 
</menu> 

及び注入menuを有するheader-menuコンポーネントは、このコンポーネントは

header-menu 
    menu 
    auth-logout 
     menu-item 

更新/回答をネストでは動作しない追加された: 最終的なケースはheader-menuです。この問題はgithub.com/aですngular/angular/issues/5126であり、これはまだサポートされていません。

答えて

2

@Host()デコレータを削除して、privateを忘れないでください。そうでない場合は、this.menuComponentはの修正なしで常にundefinedになります。

constructor (@Optional() private menuComponent: MenuComponent) 

Plunker Example

+0

HM、それは私が 'private'を見逃しているのは奇妙です。 Y'r right、それは私の例では動作しますが、これは実際のアプリケーションでは動作しません。もう少しデバッグして質問にUpdateを追加してください。 – drow

+0

角ざらざらで答えました:このケースでは現在サポートされていません - https://github.com/angular/angular/issues/5126 – drow

0

ここに変更されたplunkrがあります。
これは、インスタンスを通過させる方法の1つです。Template reference variablesを使用します。
注射は私にとっては複雑すぎる。 AUTH-logout.component.tsにおいて

<menu-item (itemClick)="logout()" [menu]="menu"> 
    LOGOUT 
</menu-item> 

@Input() menu: MenuComponent; 

AUTH-logout.component.htmlにおいて

<menu #mm><!-- use whatever name after # --> 
    <auth-logout [menu]='mm'></auth-logout> 
</menu> 

:app.component.htmlで

menu-item.component.ts内:

@Input() menu: MenuComponent; 

#mm(MenuComponentのインスタンス)は、menuとしてauth-logoutに渡され、次にmenuというメニュー項目に続いて、メニュー項目にmenu.close()と呼び出すことができます。