【发布时间】:2019-05-29 09:44:10
【问题描述】:
我想通过单击菜单图标(在标题组件中)来切换侧导航(在抽屉组件中)。我试过使用服务;但是服务状态并没有在这两个组件之间共享。
【问题讨论】:
-
出现问题是因为 vscode 没有检查 html 关闭标签,Angular 也没有检查模板中的这个错误。
我想通过单击菜单图标(在标题组件中)来切换侧导航(在抽屉组件中)。我试过使用服务;但是服务状态并没有在这两个组件之间共享。
【问题讨论】:
您应该使用@Input 和@Output 装饰器和EventEmitter 将事件从一个组件发送到另一个组件。
我已经修复了你的代码,
请检查一下:
stackblitz
【讨论】:
Angular 提供了非常强大的Input, Output 概念。
请考虑使用Input, Output and EventEmitter
有了这些,您就可以将事件从一个组件反弹到另一个组件。
请看一下这个demo link。
// drawer.component.ts
export class DrawerComponent implements AfterViewInit, OnChanges {
@ViewChild('sidenav') public sidenav: MatSidenav;
@Input()
openNav: boolean;
ngOnChanges(): void {
console.log('ngOnChanges', this.openNav);
if (this.openNav) {
this.sidenav.open();
} else {
this.sidenav.close();
}
}
}
// header.component.ts
export class HeaderComponent implements OnInit {
title: string = "Dashboard";
@Output()
open: EventEmitter<boolean> = new EventEmitter();
clickMenu() {
this.open.emit(true);
}
}
// layouts.component.html
<div class="app-wrapper">
<app-drawer [openNav]="isOpen"></app-drawer>
<app-header (open)="navOpen($event)"></app-header>
<div>
// layouts.component.ts
export class LayoutsComponent implements OnInit {
isOpen: boolean;
navOpen($event): void {
this.isOpen = !this.isOpen;
console.log('navOpen', $event);
}
}
还可以在需要时使用相应的组件生命周期挂钩。
【讨论】:
我解决了这个问题,方法是不在服务中设置 sidenav,而是在 sidenav 需要切换时将服务变成通知程序。因此,当您单击按钮时,服务会告诉行为主体发出它对 DrawerComponent 的更改。该组件订阅 ngOnInit 中的行为主题。并在服务通知切换组件时切换 sidenav。
以下 StackBlitz 展示了我如何修复您的代码:https://stackblitz.com/edit/angular-mgm4xn
【讨论】: