I am trying to toggle a side nav menu, located at the top of my main App template using a button in a nested child component. I can't figure out how to get to the sidenav component in the parent to tell it to sidenav.open()
.
I know about @Input and @Output on a child component, but as I understand it, to use this I need to have some sort of DOM tag for the child component to attach these to? Such as:
<app>
<sidenav-component #sidenav>...</sidenav-component>
<child [someInput]="some_parent_var" (childOpensNav)="sidenav.open()"></child>
</app>
Tons of articles on how to do this. Problem is that I'm routing to this component so no <child>
tag exists explicitly in the code. Rather my code is like this:
<app>
<sidenav-component #sidenav>...</sidenav-component>
<router-outlet></router-outlet>
</app>
If I have a child component that gets routed to, how do I do a sidenav.open()
or somehow access a component in the parent from the child?
Some thoughts: I've done some research and thinking about a couple of approaches and not sure if they are correct or would even work...One approach being using the Injector service and trying to traverse up to the parent, but this feels wrong:
// child component
constructor(injector: Injector) {
this.something = injector.parent.get(Something);
}
Or possibly creating a Service in the parent, somehow attached to the Sidenav component and then injecting this service into the child??
I like the accepted answer, seems a more robust Angular way to do it properly (especially if you are going to be adding more options).
However, I wanted quick dirty access to a global element by Id. Everybody talks about using @ViewChild but I want to walk UP the tree. I just went back to school and used this in the component method:
If we want multiple copies of this to work (e.g. left and right side menus) we need to inject something down the children so they know which Id to look for.
The easiest and cleanest way is indeed to leverage a service.
The service how it could look like:
In your
bootstrap
call add the service to the list of providers:In the components (maybe in
app.ts
but also in yoursidenav.ts
) where you want to show/hide the sidebar add the service for injection:In your template, where you want to toggle/show/hide you can do now: