2016-06-11 87 views
10

我想切換側邊導航菜單,位於我的主要應用程序模板的頂部使用嵌套子組件中的按鈕。我無法弄清楚如何到父母的sidenav組件,告訴它sidenav.open()訪問父@分量和變量*路由*子組件

我知道@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

最簡單和最乾淨的方式確實是利用服務。

怎麼可能看起來像服務:

export class DomService { 
    sidebarVisible: boolean = true; 

    showSidebar() { 
     sidebarVisible = true; 
    } 

    hideSidebar() { 
     sidebarVisible = false; 
    } 

    toggleSidebar() { 
     sidebarVisible = !sidebarVisible; 
    } 
} 

在你bootstrap通話服務添加到供應商的名單:

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,謝謝。我會盡快嘗試。雖然在'@ ViewChild'可用時必須創建一個訪問DOM元素的服務,但它似乎違反直覺,似乎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'; 

如果我們想這多份工作(例如,左,右側菜單),我們需要注入下來的東西孩子們,讓他們知道哪些編號尋找。