In header.component.html there is a button, by pressing which the menu in users.component.html should open. By clicking on the button a class is added to it. How can I add a class to a menu that is in another component (preferably without jQuery)?

Plunker link

header.component.ts

import {Component} from '@angular/core'; import {Router} from "@angular/router"; import {GlobalService} from "../../global.service"; @Component({ selector: 'header', providers: [GlobalService], templateUrl: 'app/_components/header/header.component.html' }) export class HeaderComponent{ public activeMobileMenuAdmin = false; public activeClass = false; constructor(public router: Router, public globalService: GlobalService){ router.events.subscribe((val) => { if (val.url === '/login' || val.url === '/users') { this.adminPanelView = false; } else { this.adminPanelView = true; } if (val.url === '/users'){ this.adminMenuView = true; this.detectDeviceWidth(); } else { this.adminMenuView = false; } }); this.activeClass = globalService.activeClass; } admMenuShow(){ this.activeClass = !this.activeClass; } ngOnInit() { this.detectDeviceWidth(); } detectDeviceWidth() { if (window.innerWidth < 1024) { this.activeMobileMenuAdmin = true; } else { this.activeMobileMenuAdmin = false; } } } 

header.component.html

 <div class="menu-icon show-on-sm" [ngClass]="{'active': activeClass}" (click)="admMenuShow();" *ngIf="adminMenuView"> <span></span> <span></span> <span></span> 

users.component.ts

 import {Component} from '@angular/core'; import {GlobalService} from "../../global.service"; @Component({ selector: 'admin', providers: [GlobalService], templateUrl: 'app/admin/users/users.component.html' }) export class AdminUsersComponent { private activeClass = true; constructor(public globalService: GlobalService){ this.activeClass = globalService.activeClass; } admMenuShow(){ this.activeClass = !this.activeClass; } } 

users.component.html

 <div class="menu" id="admin-menu" [ngClass]="{'active': activeClass}"> <div class="contflex"> <div class="h1">Test</div> <ul> <li class="active">List 1</li> <li>List 2</li> <li>List 3</li> </ul> </div> 

global.service.ts

 import {Injectable} from '@angular/core'; import {Router} from '@angular/router'; @Injectable() export class GlobalService { public user: Object = {}; public hideMenu: boolean = true; public activeClass: boolean = false; constructor(public _router: Router) {} admMenuShow(){ return this.activeClass = !this.activeClass; } onAuthError() { console.log('Works!'); } } 

The whole page has the following structure:

 <header> ... <div class="menu-icon show-on-sm" [ngClass]="{'active': activeClass}" (click)="admMenuShow();" *ngIf="adminMenuView"> <span></span> <span></span> <span></span> </div> ... </header> <main> <router-outlet></router-outlet> <admin> ... <div class="menu" id="admin-menu" [ngClass]="{'active': activeClass}"> <div class="contflex"> <div class="h1">Menu</div> <ul> <li class="active">List 1</li> <li>List 2</li> <li>List 3</li> </ul> </div> </div> ... </admin> </main> 
  • at least through the service. Add more markup where you use them together - Grundy
  • @Grundy added. I do not know how correctly through the service. I tried to do it, but missed something. - neek

1 answer 1

It would be much easier if there was a plunkr with a ready-made example. In this code, you need to remove GlobalService from the providers component and add it to the module common to them (if there is no separate module then in main). Otherwise, you create two independent instances of the service. In the components, the variable activeClass and assignment in the constructor are removed, in the template instead of [ngClass]="{'active': activeClass}" write [ngClass]="{'active': globalService.activeClass} . Alternatively, in the service, make EventEmitter and subscribe to it in components.

 export class GlobalService { private _show: boolean = false; public onMenuStateChanged: EventEmitter<boolean> = new EventEmitter<boolean>(); toggleMenu() { this._show = !this._show; this.onMenuStateChanged.emit(this._show); } } 

-

 export class AdminUsersComponent { private activeClass = true; constructor(public globalService: GlobalService){ this.globalService.onMenuStateChanged.subscribe( state => this.activeClass = state ); } admMenuShow(){ this.activeClass = !this.activeClass; } } 

I hope the idea is clear