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??
In the parent component, declare the property that you want to receive in the child component, say 'ParentId'. While including the child component inside the parent component, bind the 'ParentId' property to the child component using property binding.
If you want to pass data from the parent component to the child component, you need to use two things: @Input and property binding. In this example, we set in the child component a variable named childExample , which is a string. We set Angular's @Input decorator in front of the variable.
The easiest and cleanest way is indeed to leverage a service.
The service how it could look like:
export class DomService {
sidebarVisible: boolean = true;
showSidebar() {
sidebarVisible = true;
}
hideSidebar() {
sidebarVisible = false;
}
toggleSidebar() {
sidebarVisible = !sidebarVisible;
}
}
In your bootstrap
call add the service to the list of providers:
bootstrap(App, [
// other providers
DomService
]);
In the components (maybe in app.ts
but also in your sidenav.ts
) where you want to show/hide the sidebar add the service for injection:
constructor(private _domService: DomService) {
}
In your template, where you want to toggle/show/hide you can do now:
<sidenav-component *ngIf="_domService.sidebarVisible">...</sidenav-component>
<div id="toggle-sidebar" (click)="_domService.toggleSidebar()">toggle</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With