1
votes

I have a parent component with a <router-outlet> inside of it, the parent has a menu to direct to these routes, and the menus have sub menus that are drop-downs. Currently, the active route is highlighted in the menu at all times, but if that menu option is a sub-menu it isn't showing unless you open it. I want to keep that sub-menu open if the route is within it.

I want to manage this in one place, the parent. My current attempt gets the current route url, and checks if it contains the sub-menu route string. The problem with this method is I can't find a life-cycle hook that will get the current route every time the route is changed for the child routes. In other words, a life-cycle hook that detects a new child component being rendered.

As a side note, is my Renderer accessing the DOM in a bad way since it uses the native element?

html:

  <div
                        class="dropdown"
                        appDropdown
                        #DropdownOne
                    >
                        <button
                            class="top item btn btn-secondary dropdown-toggle"
                            type="button"
                            id="dropdownMenuButton"
                            data-toggle="dropdown"
                            aria-haspopup="true"
                            aria-expanded="false"
                        >
                            all options
                        </button>
                        <div
                            class="item dropdown-menu"
                            aria-labelledby="dropdownMenuButton"
                        >
                            <a
                                class="dropdown-item"
                                routerLink="/myMenu/options/option1"
                                routerLinkActive="active"
                            >
                            option 1</a>
                            <a
                                class="dropdown-item"
                                routerLink="/myoptions/options/option2"
                                routerLinkActive="active"
                            >
                            Option 2</a>
                            <a
                                class="dropdown-item"
                                routerLink="/myoptions/options/option3"
                                routerLinkActive="active"
                            >
                            Option 3</a>
                         </div>
    </div>
...
<div class="content-box col">
            <router-outlet></router-outlet>
</div>
...

ts

export class NetworkComponent implements AfterViewInit {
    @ViewChild('DropdownOne') dropdownOne: ElementRef;
    @ViewChild('DropdownTwo') dropdownTwo: ElementRef;
    url: string;
    // stateOne = 'closed';
    // stateTwo = 'closed';

    constructor(private router: Router,
                private renderer: Renderer2) {}

    ngAfterViewInit() {
        this.url = this.router.url;
        console.log(this.url)
        if (this.url.includes('interface')) {
            console.log('TRUE')
            this.renderer.addClass(this.dropdownOne.nativeElement, 'show')
        }
        if (this.url.includes('firewall')) {
            console.log('TRUE')
            this.renderer.addClass(this.dropdownTwo.nativeElement, 'show')
        }
    }
1

1 Answers

-1
votes

You could subscribe to the Router events observable.

constructor(private router: Router, private renderer: Renderer2) {
    this.router.events.subscribe(() => {
        const url = this.router.url;
        // do your route check here
    });
}

You can read more on the Router here: https://angular.io/api/router/Router#events

For your side note on using the Renderer, I think you could achieve the same effect using a simple boolean like so,

<div appDropdown class="dropdown" [class.show]="isDropdownOneOpen"> ... </div>

Just set it to true when the route matches.