您真正想做的是管理应用程序的(全局)状态。
选项 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。这个想法类似于使用自己的状态服务,除了整个状态保存在一个状态对象中,并且这些库引入了更复杂的概念。