2016-06-11 12 views
10

私は、ネストされた子コンポーネント内のボタンを使用して、私のメインのアプリケーションテンプレートの上部にあるサイドナビゲーションメニューを、切り替えしようとしています。私は親のsidenavコンポーネントに到達してsidenav.open()に伝える方法を理解できません。アクセス親@ComponentとVARS

私は、子コンポーネントの@Inputと@outputについて知っているが、私はそれを理解するように、私はこれらを添付する子コンポーネントのためのDOMタグのいくつかの並べ替えを持っている必要があり、これを使用しますか?のような:

<app> 
    <sidenav-component #sidenav>...</sidenav-component> 

    <child [someInput]="some_parent_var" (childOpensNav)="sidenav.open()"></child> 
</app> 

これを行う方法の記事のトン。問題は私がをこのコンポーネントにルーティングしているので、コードに明示的に存在する<child>タグがないことです。むしろ私のコードは次のようである:

<app> 
    <sidenav-component #sidenav>...</sidenav-component> 

    <router-outlet></router-outlet> 
</app> 

私がルーティングされる子コンポーネントを持っている場合、私はsidenav.open()を行うか、何らかの形で子から親にコンポーネントにアクセスする方法は?

いくつかの研究を行い、いくつかのアプローチについて考えていて、それらが正しいかどうかわからない... Injectorサービスを使用していて、親、しかし、これは間違っている感じ:

// child component 
constructor(injector: Injector) { 
    this.something = injector.parent.get(Something); 
} 

または可能性の親でサービスを作成し、何とかSidenav成分に結合して、子供にこのサービスを注入する??

+0

これはまさに私がやろうとしていることです。あなたの質問を見つけたとは思えません。ありがとう。うまくいけば私は下にスクロールし、良い答えを得るでしょう。 – krummens

答えて

9

最も簡単でクリーンな方法は、実際にサービスを活用することです。

それはように見える可能性がどのようにサービス:プロバイダのリストにサービスを追加するには、bootstrapコールで

export class DomService { 
    sidebarVisible: boolean = true; 

    showSidebar() { 
     sidebarVisible = true; 
    } 

    hideSidebar() { 
     sidebarVisible = false; 
    } 

    toggleSidebar() { 
     sidebarVisible = !sidebarVisible; 
    } 
} 

:コンポーネントで

bootstrap(App, [ 
    // other providers 
    DomService 
]); 

(多分app.tsでなく、あなたの中にsidenav.ts)サイドバーを表示/非表示にしたい場合は、注入サービスを追加します。

constructor(private _domService: DomService) { 

} 
あなたは/あなたが今行うことができます表示/非表示を切り替えたいあなたのテンプレートでは、

:私は受け入れ答えを好き

<sidenav-component *ngIf="_domService.sidebarVisible">...</sidenav-component> 

<div id="toggle-sidebar" (click)="_domService.toggleSidebar()">toggle</div> 
+2

Intersting、ありがとうございます。私はすぐにこれを試してみます。しかし、直感的ではありませんが、DOM要素にアクセスするためのサービスを作成する必要があります。@ ViewChildが利用可能な場合、Angular 2は、@ ViewParentなどのようなものを提供する可能性があります。それが私のためにどのように行くのかを教えてくれます。また、どのようにしてこの回答に至りましたか/これが「ベストプラクティス」であることを知りましたか?ありがとう! – FireDragon

+0

さて、基本的には、[入力と出力のプロパティ](https://angular.io/docs/ts/latest/guide/template-syntax.html#!#input-and-output-properties)でこれを行うことができます'sidenav-component'タグが付いていますが、他の場所からそれが必要な場合は、本当に面倒です。 – rinukkusu

0

、あなたが行っている場合は特に(それを正しく行うには、より堅牢な角度な方法と思われますオプションを追加する)。

しかし、私は、IDでグローバル要素への迅速な汚いのアクセスを望んでいました。みんな@ViewChildの使い方について話していますが、私はツリーを歩きたいです。私は学校に戻って行き、コンポーネント方法でこれを使用:

document.getElementById('nav-panel').className = 'hide'; 

我々が動作するように、このの複数のコピーをしたい場合(例えば左右のサイドメニュー)我々は、彼らが知っているので、子供たちの下に何かを注入する必要があります見なければならないのは、

関連する問題