我有两个组件,AppNav组件和Machines组件。 AppNav组件具有工具栏和sidenav。我还在AppNav的工具栏上放置了一个筛选器按钮。在“机器组件”中,有一个垫子抽屉,在单击AppNav工具栏上的过滤器按钮后,需要切换它。问题是我不知道如何使两者交流。 Machines组件不是AppNav组件的直接子组件,因为我是通过放置在AppNav的sidenav内容中的路由器出口来加载其他组件(机器等)的。
从下面查看组件:
DrawerService(我想通过创建来减轻我的挫败感)
import { Injectable } from '@angular/core';
import { MatDrawer } from '@angular/material';
@Injectable({
providedIn: 'root'
})
export class DrawerService {
private drawer: MatDrawer;
/**
* setDrawer
*/
public setDrawer(flyout: MatDrawer) {
this.drawer = flyout;
}
/**
* open
*/
public open() {
return this.drawer.open();
}
/**
* close
*/
public close() {
return this.drawer.close();
}
/**
* toggle
*/
public toggle(): void {
this.drawer.toggle();
}
}
机器组件(machines.component.ts)
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-machines',
templateUrl: './machines.component.html',
styleUrls: ['./machines.component.sass']
})
export class Machines implements OnInit {
constructor() { }
ngOnInit() {
}
}
机器html(machines.component.html)
<mat-drawer-container
fxFlexFill>
<mat-drawer
mode="side"
opened
position="end"
#flyout
class="mat-elevation-z3"
[style.width]="'200px'">
<mat-toolbar>
<span>Filter</span>
<span fxFlex></span>
<mat-icon
svgIcon="close"
(click)="flyout.toggle()"></mat-icon>
</mat-toolbar>
<mat-list>
<mat-list-item>01</mat-list-item>
<mat-list-item>02</mat-list-item>
<mat-list-item>03</mat-list-item>
<mat-list-item>04</mat-list-item>
</mat-list>
</mat-drawer>
<mat-drawer-content>
<div>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Saepe, id assumenda ratione quaerat at itaque dolorem sit ipsam, modi nam voluptatem nisi expedita quis possimus ea a sed neque? Iure!
</div>
</mat-drawer-content>
</mat-drawer-container>
AppNav组件(app-nav.component.ts)
import { Component, ViewChild, ViewChildren } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ThemeService } from '../services/theme.service';
import { DrawerService } from '../services/drawer.service';
import { MatDrawer } from '@angular/material';
@Component({
selector: 'app-nav',
templateUrl: './nav.component.html',
styleUrls: ['./nav.component.sass']
})
export class AppNav {
yearTodate: number = new Date().getFullYear();
isDarkTheme: Observable<boolean>;
links: Array<Object>;
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
.pipe(
map(result => result.matches)
);
@ViewChildren('flyout') public flyout: MatDrawer;
constructor(
private breakpointObserver: BreakpointObserver,
private drawerService: DrawerService,
private themeService: ThemeService) {}
ngOnInit() {
this.isDarkTheme = this.themeService.isDarkTheme;
this.links = this.linksArray;
this.drawerService.setDrawer(this.flyout);
}
toggleDarkTheme(checked: boolean) {
this.themeService.setDarkTheme(checked);
}
toggleFlyout () {
this.drawerService.toggle();
}
linksArray = [
{
route: "/dashboard",
icon: "ballot",
name: "Dashboard"
},
{
route: "/vehicles",
icon: "car",
name: "Vehicles"
}
]
}
AppNav html(app-nav.component.html)
<div
[ngClass]="{'dark-theme': isDarkTheme | async}"
fxLayout="column"
fxLayoutAlign="center center"
fxFlexFill
class="mat-app-background"
style="position: relative">
<mat-sidenav-container class="sidenav-container">
<mat-sidenav
#drawer
class="sidenav mat-elevation-z3"
fixedInViewport="true"
[attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
[mode]="(isHandset$ | async) ? 'over' : 'side'"
[opened]="!(isHandset$ | async)"
fxLayout="column">
<mat-nav-list>
<a
mat-list-item
routerLink="{{link.route}}"
*ngFor="let link of links">
<mat-icon svgIcon="{{link.icon}}"></mat-icon>
<span fxFlex="5"></span>
<span>{{link.name}}</span>
</a>
</mat-nav-list>
<span fxFlex></span>
<mat-nav-list>
<a
mat-list-item
routerLink="/login">
<mat-icon svgIcon="login"></mat-icon>
<span fxFlex="5"></span>
<span>Login</span>
</a>
</mat-nav-list>
<mat-divider></mat-divider>
<small
style="padding: 16px">
©{{yearTodate}} MotionPlus
</small>
</mat-sidenav>
<mat-sidenav-content
fxLayout="column">
<mat-toolbar
color="primary">
<button
type="button"
aria-label="Toggle sidenav"
mat-icon-button
(click)="drawer.toggle()"
*ngIf="isHandset$ | async">
<mat-icon
aria-label="Side nav toggle icon"
svgIcon="menu">
<!-- menu -->
</mat-icon>
</button>
<span>MotionPlus</span>
<span fxFlex></span>
<button
mat-icon-button
(click)="toggleFlyout()">
<mat-icon svgIcon="filter-variant"></mat-icon>
</button>
<button
mat-icon-button
[matMenuTriggerFor]="bucket">
<mat-icon
svgIcon="format-color-fill"></mat-icon>
</button>
<mat-menu
#bucket="matMenu">
<button
mat-menu-item
(click)="toggleDarkTheme(true)"
fxLayout="column"
fxLayoutAlign="center center">
<span
style="
background: purple;
width: 42px;
height: 42px;
border-radius: 50%">
</span>
</button>
<button
mat-menu-item
(click)="toggleDarkTheme(false)"
fxLayout="column"
fxLayoutAlign="center center">
<span
style="
background: yellow;
width: 42px;
height: 42px;
border-radius: 50%">
</span>
</button>
</mat-menu>
</mat-toolbar>
<!-- Add Content Here -->
<div
style="padding: 0 24px;"
fxFlex>
<router-outlet></router-outlet>
</div>
</mat-sidenav-content>
</mat-sidenav-container>
</div>
为我指出如何实现此目标的正确方向。我想控制AppNav组件中Machines组件(通过Router-Outlet动态加载)中的Mat-Drawer的打开和关闭。
答案 0 :(得分:1)
抽屉所在的组件
export class DashboardComponent implements OnInit {
@ViewChild('drawer') public drawer: MatDrawer;
ngOnInit() {
this.toolbarService.setDrawer(this.drawer);
}
}
带有切换按钮的组件。这是带有抽屉的组件的子代:
export class PageToolbarComponent implements OnInit {
toggleDrawer() {
this.toolbarService.toggle();
}
}
共享服务:
private drawer: MatDrawer;
setDrawer(drawer: MatDrawer) {
this.drawer = drawer;
}
toggle(): void {
this.drawer.toggle();
}
这对我有用。 For more details