Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access Parent @Component and vars from *Routed* Child Component

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??

like image 845
FireDragon Avatar asked Jun 11 '16 22:06

FireDragon


People also ask

How do you access the parent component property in a child component?

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.

How do you use the parent component variable in a child component?

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.


1 Answers

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>
like image 177
rinukkusu Avatar answered Sep 21 '22 15:09

rinukkusu