На самом деле вы хотите управлять (глобальным) состоянием вашего приложения.
Вариант 1 : Использование вложенных компонентов
Если у вас есть родитель - и дочерний компонент, просто используйте EventEmitters . Может выглядеть так:
nav.ts
export enum MenuName = {
Menu1 = 'Menu 1',
Menu2 = 'Menu 2'
}
export const navItems: INavData[] = [
{
name: MenuItem.Menu1,
...
},
];
child.component.ts
@Output() badgeChange = new EventEmitter<{menuName: MenuName, value: string}>();
private updateBadge(menuName: MenuName, value: string) {
this.badgeChange.next({menuName, value});
}
и слушайте к изменению в ваших родителях HTML: <app-child (badeChange)="onBadgeChanged($event)"></app-child>
и в TS:
onBadgeChanged(change: {menuName: MenuName, value: string}): void {
// find menu item by `change.menuName`
// update it's badge value
}
Вариант 2 : Используйте сервис для глобального состояния
Если ваш глобальный состояние простое, вы также можете использовать службу для своего состояния:
nav-service.ts
export class NavService {
navData$ = new BehaviourSubject<INavData[]>([
{
name: "Menu 1",
...
},
]);
updateBadge(menuItemName: string, value: string): void {
// find menu item by `menuItemName` in `this.navData$.value`
const menuItem = ...;
if (menuItem) {
menuItem.badge.text = value;
this.navData$.next([...this.navData$.value]); // emit new nav data
}
}
}
В этом случае ваш компонент меню будет слушать при изменении this.navService.navData$
, а компонент или служба, обновляющая данные, использует this.navService.updateBadge(...)
, чтобы сообщить всем, что значение изменилось.
Вариант 3 : использовать библиотеку управления состоянием
Если ваше состояние сложнее, чем просто меню, я бы предложил использовать библиотеку состояний, такую как NgRx , NgXs или Akita . Перейдите по ссылкам, чтобы узнать о них больше, я использую NgRx для своих проектов. Идея аналогична использованию собственной службы для состояния, за исключением того, что все состояние хранится в одном объекте состояния, и эти библиотеки вводят более сложные концепции.