2017-10-25 9 views
2

私はそれぞれAngular2とTypescriptの周りに頭を抱えようとしています。私がしたいのは、子コンポーネントにあるボタンから、ここではapp-headerというボタンからsidenavを開きます。子供の親からテンプレート参照変数にアクセスするには?

私は

<button mat-button (click)="sidenav.open()">Open sidenav</button> 

でそれを開くことができますが、それはテンプレート変数の参照sidenavを参照すると、私は親テンプレートの中にこれを置く場合にのみ動作します知っています。しかし、私が言ったように、私は子供のボタンをクリックすることに基づいてそれを開きたい。

これは私のレイアウト/アプリテンプレートのようになります。

<mat-sidenav-container> 
    <mat-sidenav #sidenav> 
    <!-- sidenav content --> 
    Here comes the menu .. 
    </mat-sidenav> 

    <div>  
    <app-header> 
     <!-- Application header --> 
    </app-header> 
    </div> 

</mat-sidenav-container> 

そして、これは、ヘッダーテンプレートのようになります。私はsidenavを参照することはできませんので、もちろん

これは失敗した - ので、どのように私はアクセスすることができますsidenav子供の中から正しく?

またはAngular2に「no no」というような参照を渡していますが、実際にはイベントベースのトリガーなどを使用する必要がありますか?

+0

正確に言及しているsidenav変数とは何ですか?そのコードを私たちに見せてもらえますか? –

答えて

2

これは通常の親子コンポーネント通信です。あなたがこれを行うことが方法は、ちょうど子供に出力イベントを公開することです:

parent.component.htmlの抜粋:

<child-component (openNav)="sidenav.open()"></child-component> 

、あなたはちょうどそのイベントを放出するボタンのクリックをバインド子で:

child.component.ts:

@Output() openNav = new EventEmitter(); 

child.component.html:

もつとも

、これは多くの場所で多分、ネストされた場所にアクセスする必要があるかもしれsidenavで、あなただけのすべての状況で問題を解決し、共有サービス、観察を使用する場合がありますので、:

側nav.service.ts:

@Injectable() 
export class SideNavService { 
    private openNavSource = new Subject(); // never expose subjects directly 
    openNav$ = this.openNavSource.asObservable(); 

    openNav =() => this.openNavSource.next(); 
} 

が適切に提供し、使用のために親と子に注入

parent.component.ts:

@ViewChild('sidenav') sidenav; // get your template reference in the component 
constructor(private sideNavService: SideNavService) { } 
private sideNavSub; 
ngOnInit() { 
    this.sideNavSub = this.sideNavService.openNav$.subscribe(() => this.sidenav.open()); 
} 
ngOnDestroy() { 
    this.sideNavSub.unsubscribe(); //clean your subscriptions 
} 

child.component.ts:

constructor(private sideNavService: SideNavService) { } 
openNav() { 
    this.sideNavService.openNav(); // looks repetitive but accessing injectd services in templates is bad practice and will cause pains down the line 
} 

child.component.html:

<button (click)="openNav()">Open Nav</button> 

、あなたが任意のコンポーネントにサービスを注入し、必要に応じて使用することができます。

+0

非常に素晴らしい!これらの2つのアプローチを提供していただきありがとうございます。 :) – displayname

+0

私は小さな質問をしてもいいですか: '(openNav)'のようなそのような "パラメータ"は何ですか?それは子供のビューのコンストラクタ引数のいくつかの並べ替えですか?そして、最初の例で '@ Output'ではなく' @ Output'ではないのはなぜですか? – displayname

+1

(openNav)は標準的な角度出力イベントバインディングです。子コンポーネントはイベントを出力しており、親はその構文でバインドします。 @Outputは、子から生成された出力であり、親から子に渡される入力ではないためです。たとえば、よく知っている(クリック)= ""構文です。クリックは簡単なバインディングのためにネイティブHTMLコンポーネントから出力される角度フレームワークです。 – bryan60

関連する問題