2016-06-11 41 views
10

Sto cercando di attivare un menu di navigazione laterale, che si trova nella parte superiore del mio modello di app principale utilizzando un pulsante in un componente figlio nidificato. Non riesco a capire come arrivare al componente sidenav nel genitore per dirlo a sidenav.open().Access Parent @Component e vars da * Routed * Componente figlio

Conosco @Input e @Output su un componente figlio, ma, a quanto ho capito, per utilizzarlo è necessario disporre di una sorta di tag DOM per il componente figlio a cui collegarli? Ad esempio:

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

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

Tonnellate di articoli su come procedere. Il problema è che io sono routing a questo componente quindi nessun tag <child> esiste esplicitamente nel codice. Piuttosto il mio codice è simile a questo:

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

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

Se ho un componente figlio che viene instradata verso, come faccio a fare un sidenav.open() o in qualche modo accede a un componente nel genitore del bambino?

Alcune considerazioni: ho fatto qualche ricerca e ho riflettuto su un paio di approcci e non sono sicuro se sono corretti o funzionerebbero ... Un approccio sta usando il servizio Injector e proviamo a passare al genitore, ma questo si sente male:

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

O forse la creazione di un servizio nel genitore, in qualche modo collegato al componente Sidenav e quindi l'iniezione di questo servizio nel bambino ??

+0

Questo è letteralmente esattamente quello che sto cercando di fare. Non posso credere di aver trovato la tua domanda. Grazie. Spero di scorrere verso il basso e ottenere una buona risposta. – krummens

risposta

9

Il modo più semplice e pulito è quello di sfruttare un servizio.

Il servizio di come potrebbe sembrare:

export class DomService { 
    sidebarVisible: boolean = true; 

    showSidebar() { 
     sidebarVisible = true; 
    } 

    hideSidebar() { 
     sidebarVisible = false; 
    } 

    toggleSidebar() { 
     sidebarVisible = !sidebarVisible; 
    } 
} 

Nel vostro bootstrap chiamata aggiungere il servizio all'elenco dei fornitori:

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

Nei componenti (forse in app.ts ma anche nella vostra sidenav.ts) in cui si desidera mostrare/nascondere la barra laterale aggiungere il servizio per l'iniezione:

constructor(private _domService: DomService) { 

} 

Nel modello, in cui si desidera attivare/mostra/nascondi si può fare ora:

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

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

Intersecando e grazie. Ci proverò presto.È controintuitivo però dover creare un servizio per accedere agli elementi DOM quando è disponibile '@ ViewChild', sembra che Angular 2 possa fornire qualcosa come' @ ViewParent' o qualcosa per renderlo più intuitivo? Ti farò sapere come va per me però. Inoltre, come sei arrivato a questa risposta/venuto a sapere che si tratta di "migliori pratiche"? Grazie! – FireDragon

+0

Bene, in pratica puoi farlo con [proprietà di input e output] (https://angular.io/docs/ts/latest/guide/template-syntax.html#!#input-and-output-properties) sul tuo tag 'sidenav-component', ma se ne hai bisogno da qualche altro punto, questo diventerà davvero disordinato. – rinukkusu

0

mi piace la risposta accettata, sembra un modo angolare più robusto per farlo correttamente (soprattutto se si sta andando aggiungere ulteriori opzioni).

Tuttavia, volevo un rapido accesso sporco a un elemento globale da Id. Tutti parlano dell'utilizzo di @ViewChild, ma voglio salire sull'albero. Sono appena tornato a scuola e usato questo nel metodo componente:

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

Se vogliamo più copie di questo lavoro (ad esempio, menu a sinistra e lato destro) abbiamo bisogno di iniettare qualcosa verso il basso i bambini in modo che sappiano che Id per cercare.