As you are looking for a more 'Angular Way' to proceed, here is another way, using Service coupled with RxJs. The idea is to have a MenuService which will store the active button reference as Subject. Your buttons will be able to subscribe to that Subject, receiving the new button reference when it changes. Testing that value in your button template will allow you to apply or not the active class.
This example can be elaborated with richer functions, but for explanation purposes, I will keep it as simple as it should be to answer the OP question.
First, create a new Interface (or Class, as you prefer) to define your button model. In this case, I will call it MenuItem. In this example, MenuItem.ts is stored here /src/app/_models/
MenuItem.ts
export interface MenuItem {
label: string;
routerLink: string;
}
Then, create the MenuService service. Here, you will need to declare a BehaviourSubject to store the reference of the clicked button. Using this method, you will be able to call .next() each time a new button is clicked and becomes the active one.
menu.service.ts
import { MenuItem } from 'src/app/_models/MenuItem'
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class MenuService {
$activeButton: BehaviorSubject<MenuItem> = new BehaviorSubject<MenuItem>({} as MenuItem);
constructor() {}
}
Next, create a component that will use a MenuItem as Input() property. Don't forget to inject MenuService. Therefore, you will be able to subscribe to the current active button stored in the service.
menu.button.component.ts
@Component({
selector: 'app-menu-button',
templateUrl: './menu-button.component.html',
styleUrls: ['./menu-button.component.scss']
})
export class MenuButton implements OnInit {
@Input() menuItem: MenuItem = {} as MenuItem;
isActive: boolean = false;
constructor(private menuService: MenuService) {}
ngOnInit(): void {
this.menuService.$activeButton.subscribe((activeButton) => this.isActive = this.menuItem === activeButton);
}
setActive() {
this.menuService.$activeButton.next(this.menuItem);
}
}
You are now able to test the isActive property of your button and apply, or not, the desired class to it. Don't forget to capture the click event and update the $activeButton value by calling next() and passing the new menuItem value using the setActive() method written above.
menu.button.component.html
<button [routerLink]="this.menuItem.routerLink" [ngClass]="{ active: this.isActive }" (click)="this.setActive()">{{ this.menuItem.label }}</button>