我将angular 4与angular material结合使用。
我正在使用sidenav容器,路由器和自定义生成的菜单:
<mat-sidenav-container>
<mat-sidenav #sidenav>
<app-menu></app-menu>
</mat-sidenav>
<router-outlet></router-outlet>
</mat-sidenav-container>
在菜单组件中我使用默认的angular 4路由器链接:
<ul>
<li *ngFor="let hero of heroes">
<a mat-button [routerLink]="['/hero/', hero.id]" queryParamsHandling="merge">
{{hero.name}}
</a>
</li>
</ul>
我想要点击其中一个路由器链接时关闭Material sidenav
。
我可以向您保证,如果没有点击事件路由工作正常,它就不会关闭我的sidenav,因为路由器插座位于侧面导航内。
但是,当我向(click)="sidenav.close()"
添加a
时,我的整页突然刷新,而不是仅仅关注路由器链接。
我尝试了很多东西,但我似乎无法弄明白,希望有人可以提供帮助!
答案 0 :(得分:17)
这是基于Angular Material的原理图生成的sidenav布局组件的完整解决方案。通过考虑我们是否在手持设备上,并确保sidenav仅在手持设备上关闭,此答案在以前的答案上得到了改进。
几点:
my-menu
,但是您也可以使用其他任何名称。rxjs
运算符withLatestFrom
与isHandset$
流结合而完成的是由原理图生成的。import { Component, ViewChild } from '@angular/core';
import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout';
import { Observable } from 'rxjs';
import { map, filter, withLatestFrom } from 'rxjs/operators';
import { Router, NavigationEnd } from '@angular/router';
import { MatSidenav } from '@angular/material';
@Component({
selector: 'app-my-menu',
templateUrl: './my-menu.component.html',
styleUrls: ['./my-menu.component.css']
})
export class MyMenuComponent {
@ViewChild('drawer') drawer: MatSidenav;
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
.pipe(
map(result => result.matches)
);
constructor(private breakpointObserver: BreakpointObserver,
router: Router) {
router.events.pipe(
withLatestFrom(this.isHandset$),
filter(([a, b]) => b && a instanceof NavigationEnd)
).subscribe(_ => this.drawer.close());
}
}
答案 1 :(得分:4)
我创建了一个服务,以便可以从各种组件控制sidenav。我跟着this example。
然后根据需要观察路由器的事件和关闭。在app.component.ts中:
this.router.events.subscribe(event => {
// close sidenav on routing
this.sidenavService.close();
});
如果您想关闭仅特定链接上的sidenav,这不起作用,但服务本身会促进这一点。
答案 2 :(得分:3)
受到@ isherwood的回答的启发,我想出了一个解决方案:
我创建了以下服务:
DECLARE @PERCENTAGE DECIMAL --Or INT if you prefer it
DECLARE @TOTAL DECIMAL --Or INT if you prefer it
SET @TOTAL = (SELECT COUNT(*) FROM VEHICLES_FW)
SET @PERCENTAGE = (SELECT COUNT(*) FROM VEHICLES_FW
WHERE ARCHIVE_STATUS_FW = 'N'
AND LOCATION_CODE_FW IN ('L0078')) * (100 / 180)
RETURN PERCENTAGE;
我更改了我的app组件,在上面的服务中设置了sideNav属性。
import { Injectable } from '@angular/core';
import { MatSidenav } from '@angular/material';
@Injectable()
export class SidenavService {
public sideNav:MatSidenav;
constructor() { }
}
请注意,实施export class AppComponent implements OnInit {
title = 'app';
@ViewChild('sidenav') public sideNav:MatSidenav;
constructor(private sidenavService: SidenavService) {
}
ngOnInit() {
this.sidenavService.sideNav = this.sideNav;
}
}
并在OnInit
功能中设置sidenavService.sideNav
非常重要。
然后,您可以在任何地方使用sideNavService。在我的情况下,我只在我在侧面导航菜单中实际链接的组件中使用它。
示例:
ngOnInit
您可能希望在更改参数而不是在init上执行此操作,但您明白了这一点。
答案 3 :(得分:2)
还有其他一些小信息,如果您只想在移动视口上关闭sidenav,只需在调用函数之前使用isHandset$
函数检查抽屉状态:
import { ViewChild } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
@ViewChild('snav', { static: false }) usuarioMenu: MatSidenav;
isHandset$: Observable<boolean> =
this.breakpointObserver.observe(Breakpoints.Handset)
.pipe(
map(result => result.matches),
shareReplay()
);
constructor(
private breakpointObserver: BreakpointObserver) { }
closeAllSidenav() {
this.isHandset$.subscribe(isVisible => {
if(isVisible) {
this.myDrawer.close();
}
});
}
答案 4 :(得分:1)
将(click)="sidenav.close()"
添加到mat-sidenav
<mat-sidenav #sidenav mode="side" class="app-sidenav" (click)="sidenav.close()">
答案 5 :(得分:0)
您不需要为此提供服务。这是一个简单的解决方案。
<mat-sidenav-container [hasBackdrop]="true">
<mat-sidenav #sidenav mode="side" class="sideNavigation">
<mat-nav-list>
<a mat-list-item routerLink="" (click)="sidenav.close()"> bar</a>
<a mat-list-item routerLink="/bar" (click)="sidenav.close()">foo</a>
<a mat-list-item routerLink="/foo" (click)="sidenav.close()">whatever</a>
<a mat-list-item routerLink="/something1" (click)="sidenav.close()">SomePage</a>
<a mat-list-item routerLink="/something2" (click)="sidenav.close()">Some Page</a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<mat-toolbar color="accent">
<mat-icon (click)="sidenav.toggle()">menu</mat-icon>
<div class="divider"></div>
<img class="img" src="../assets/img/logo.png" alt="logo" (click)="goHome()" />
</mat-toolbar>
<router-outlet></router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>
您要做的就是添加(click)="sidenav.close()"
和routerLink="/whatever/path/here"
作品。这样将关闭sidenav
定向到页面。
答案 6 :(得分:0)
在需要调用方法的情况下,我测试了另一种解决方案,使用@ViewChild
似乎更容易,更实用,如果有人愿意,我将其留在这里。
app.component.html:
<mat-sidenav #snav mode="over" fixedTopGap="56">
<mat-nav-list class="pt-0">
<a mat-list-item (click)="closeAllSidenav()">
Navigation Item
</a>
</mat-nav-list>
</mat-sidenav>
app.component.ts:
import { ViewChild } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
@ViewChild('snav', { static: false }) usuarioMenu: MatSidenav;
closeAllSidenav() {
this.usuarioMenu.close();
}