17

I created a sidebar menu, but I am not able to hide the menu after I click on a menu item. I followed the example from https://blog.thecodecampus.de/angular-2-animate-creating-sliding-side-navigation/

Do I need to call toggleMenu on (click) of every hyper link from html? If yes, how do I call a method which is in app.component.ts from another component?

Need help please...

I am using Angular 4 with bootstrap 4.

Here is my code: app.component.html:

<button (click)="toggleMenu()" class="hamburger">
  <span>toggle menu</span>
</button>

<!--  <app-menu [@slideInOut]="menuState"></app-menu>  -->
<navigation-component [@slideInOut]="menuState"> </navigation-component>

<div class="container-fluid">
  <alert></alert>
  <router-outlet></router-outlet>
</div>

navigation.component.mobile.html:

    <li><a routerLink="/home" routerLinkActive="active"> Home</a></li>
    <li>
        <a href="#submenu1" data-toggle="collapse">Alert</a>
        <ul id="submenu1" class="list-unstyled collapse">
            <li><a routerLink="/linesidemonitor" data-toggle="collapse" data-target=".navbar-collapse.show">IQS Alert</a></li>
        </ul>
    </li>
    <li routerLinkActive="active" [hidden]="!authenticated()">
        <a href="#submenu2" data-toggle="collapse">Configuration</a>
        <ul id="submenu2" class="list-unstyled collapse">
            <li><a routerLink="/contact" data-toggle="collapse" data-target=".navbar-collapse.show">Contacts</a></li>
            <li><a routerLink="/department" data-toggle="collapse" data-target=".navbar-collapse.show">Departments</a></li>
            <li><a routerLink="/notificationlevel">NotificationLevels</a></li>
            <li><a routerLink="/recipient">Recipients</a></li>
        </ul>
    </li>

app.component.ts:

@Component({
  selector: 'app-root',
  templateUrl: './'  + (window.innerWidth > 745 ? 
          'app.component.html' :
          'app.component.mobile.html'),
  styleUrls: ['./app.component.css'],
  animations: [
               trigger('slideInOut', [
                 state('in', style({
                   transform: 'translate3d(0, 0, 0)'
                 })),
                 state('out', style({
                   transform: 'translate3d(100%, 0, 0)'
                 })),
                 transition('in => out', animate('400ms ease-in-out')),
                 transition('out => in', animate('400ms ease-in-out'))
               ]),
             ]
})
  toggleMenu() {
      // 1-line if statement that toggles the value:
      this.menuState = this.menuState === 'out' ? 'in' : 'out';
  }

enter image description here

UPDATE:

I tried to call toggleMenu(). It is working, but the page is loading again. Earlier it used to be like AJAX call(quick), but now it is like a new page loads first time. So I need help on how to do it as it done in http://parlaybuddy.razartech.com/no-auth

https://jmouriz.github.io/angular-material-multilevel-menu/demo/demo.html#!/demo/views/item-1-1

https://stackblitz.com/edit/dynamic-nested-sidenav-menu

navigation.component.ts

toggleMenu() {
    this.toggleMenu();
}

HTML:

       <ul id="submenu2" class="list-unstyled collapse">
            <li><a class="submenu" routerLink="/contact"  (click)="toggleMenu()">Contacts</a></li>
            <li><a class="submenu" routerLink="/department" (click)="toggleMenu()">Departments</a></li>

SOLUTION:

As Santosh metioned I added below code in app.component.ts and it worked as expected. Thank you Santosh

  constructor(private http: Http,
          private router: Router,
          public zone: NgZone) {
          router.events.subscribe( (event: Event) => {
              if (event instanceof NavigationStart) {
                  this.menuState = 'out';
              }

              if (event instanceof NavigationEnd) {
                  // Hide loading indicator
              }

              if (event instanceof NavigationError) {
                  // Hide loading indicator
                  // Present error to user
                  console.log(event.error);
              }
          });
  }
SK.
  • 1,390
  • 2
  • 28
  • 59
  • Would you mind putting a comment before doing negative vote??? Didn't I explain well what I am looking for or didn't I post the code which I have implemented so far or didn't I try and explain what I tried so far??? – SK. Jun 26 '18 at 13:52

5 Answers5

14

You can handle that in router events and set this.menuState to 'out' whenever route changes.

A pretty decent sample code here

Santhosh S
  • 782
  • 5
  • 17
  • Adding code in the constructor worked... Updated my question with the resolution. Thanks a lot. – SK. Jul 02 '18 at 19:23
  • 1
    This answer would be better if you included a snippet without requiring clicking to an external page. Especially since that link is a Medium page, and you can only view so many Medium articles in a month before getting locked out. – RoboticRenaissance Aug 14 '21 at 19:51
2

You have to do the toggle things in NgZone. And for that first you have to add following module.

import { NgZone } from '@angular/core';

Now create zone variable in constructor

constructor(public zone: NgZone){}

and write your toggle logic in Zone() method like following way

toggleMenu() {
    this.zone.run(()=>{
    this.menuState = this.menuState === 'out' ? 'in' : 'out';
   })
}
Chintan Kukadiya
  • 784
  • 5
  • 16
  • As Santosh mentioned, I followed that code and it worked. But I still tried this code, it didn't work for me. may be I am doing something wrong. If you can explain a little more, I will see which approach is better. Thank you. – SK. Jul 02 '18 at 19:25
0

Isn't navigation component a child component of app component. Would be nice to have full code of navigation.component.ts. How is the menu state from navigation component send to its parent? Since not sure what is happening , I have put sample code in slackblitz

https://stackblitz.com/edit/animations-in-angular4-2qwdt7?file=app%2Fnavigation.component.ts

Krishnanunni Jeevan
  • 1,719
  • 1
  • 15
  • 24
0

The navigation on every router event would be slower than solutions that only run when needed. (It will run every time when you change route by any links or calls.)

The solution can be just like here to listen to the click event and change state then.

androbin
  • 1,622
  • 14
  • 31
0

I have updated the answer below mentioned link. Toggle nav bar on the click of the sub menu

Answer Updated https://stackoverflow.com/a/58995299/714707

Surya R Praveen
  • 3,393
  • 1
  • 24
  • 25