我使用角度(最新版本)和角度材料。
有3个组成部分:
我第一次使用Angular,请告诉我,如何打开/关闭另一个组件的sidenav(在我的例子中,按钮位于header.component中)。
尝试了以下选项(但得到了错误:TypeError:this.RightSidenavComponent.rightSidenav未定义):
header.component.html
<button mat-button (click)="toggleRightSidenav()">Согласование до 16:00 сегодня</button>
&#13;
header.component.ts
import { Component } from '@angular/core';
import { RightSidenavComponent } from '../right-sidenav/right-sidenav.component';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class HeaderComponent {
constructor(public RightSidenavComponent:RightSidenavComponent) { }
toggleRightSidenav() {
this.RightSidenavComponent.rightSidenav.toggle();
}
}
&#13;
sidenav.component.html
<mat-sidenav-container class="sidenav-container">
<mat-sidenav #sidenav mode="side" opened="true" class="sidenav"
[fixedInViewport]="true"> Sidenav </mat-sidenav>
<mat-sidenav-content>
<app-header></app-header>
<router-outlet></router-outlet>
<app-right-sidenav #rSidenav></app-right-sidenav>
</mat-sidenav-content>
</mat-sidenav-container>
&#13;
sidenav.component.ts
import { Component, Directive, ViewChild } from '@angular/core';
import { RightSidenavComponent } from '../right-sidenav/right-sidenav.component';
@Component({
selector: 'app-sidenav',
templateUrl: './sidenav.component.html',
styleUrls: ['./sidenav.component.scss']
})
export class SidenavComponent {
@ViewChild('rSidenav') public rSidenav;
constructor(public RightSidenavComponent: RightSidenavComponent) {
this.RightSidenavComponent.rightSidenav = this.rSidenav;
}
}
&#13;
右sidenav.component.html
<mat-sidenav #rightSidenav mode="side" opened="true" class="rightSidenav"
[fixedInViewport]="true" [fixedTopGap]="250">
Sidenav
</mat-sidenav>
&#13;
右sidenav.component.ts
import { Component, Injectable } from '@angular/core';
@Component({
selector: 'app-right-sidenav',
templateUrl: './right-sidenav.component.html',
styleUrls: ['./right-sidenav.component.scss']
})
@Injectable()
export class RightSidenavComponent {
public rightSidenav: any;
constructor() { }
}
&#13;
答案 0 :(得分:28)
我遇到了同样的问题。我这样解决了。
SidenavService
import { Injectable } from '@angular/core';
import { MatSidenav } from '@angular/material';
@Injectable()
export class SidenavService {
private sidenav: MatSidenav;
public setSidenav(sidenav: MatSidenav) {
this.sidenav = sidenav;
}
public open() {
return this.sidenav.open();
}
public close() {
return this.sidenav.close();
}
public toggle(): void {
this.sidenav.toggle();
}
您的组件
constructor(
private sidenav: SidenavService) { }
toggleRightSidenav() {
this.sidenav.toggle();
}
根据您的要求绑定您的html toggle()。
应用组件。
@ViewChild('sidenav') public sidenav: MatSidenav;
constructor(private sidenavService: SidenavService) {
}
ngOnInit(): void {
this.sidenavService.setSidenav(this.sidenav);
}
应用模块
providers: [YourServices , SidenavService],
答案 1 :(得分:5)
如果您使用的是Angular 9+,请记住在static: true
中添加@ViewChild
的参数,例如:
@ViewChild('rightSidenav', {static: true}) sidenav: MatSidenav;
您可以在这里看到我的代码在Angular 9上运行:
https://stackblitz.com/edit/angular-kwfinn-matsidenav-angular9
答案 2 :(得分:2)
我在父组件的另一个组件中使用了#> set.seed(1337)
#> tmp<-data.frame(p = runif(99999999)*.007)
#> microbenchmark::microbenchmark(+(tmp[["p"]]<0.001) , ifelse(tmp[["p"]]<0.001, 1, 0), times = 4)
#Unit: milliseconds
# expr min lq mean median uq max neval cld
# +(tmp[["p"]] < 0.001) 463.054 527.4309 1779.396 1440.110 3031.362 3774.312 4 a
# ifelse(tmp[["p"]] < 0.001, 1, 0) 7071.470 7140.4354 8021.247 7887.672 8902.058 9238.173 4 b
,以将sideNav对象作为子组件的目标属性传递。它按预期工作。顺便说一句,我喜欢@Eldho的服务实现:)
Child.component.html
@Input() remoteSideNav: MatSideNav
layout-header.component.html
<app-layout-header [inputSideNav]="sideNav"></app-layout-header>
<mat-sidenav-container>
<mat-sidenav #sideNav (click)="sideNav.toggle()" mode="side">
<a routerLink="/">List Products</a>
</mat-sidenav>
<mat-sidenav-content>
<router-outlet></router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>
layout-header.component.ts
<section>
<mat-toolbar>
<span (click)="inputSideNav.toggle()">Menu</span>
</mat-toolbar>
</section>
答案 3 :(得分:1)
首先,您不需要在sideNav组件中调用rightSideNav。 您的切换按钮位于标题组件中。 因此,您可以在标题组件中执行此操作。
header.component.ts:
import { Component } from '@angular/core';
import { RightSidenavComponent } from '../right-sidenav/right-sidenav.component';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class HeaderComponent {
rightSideNav : boolean ;
constructor(public RightSidenavComponent:RightSidenavComponent) { }
sideNavBtnToggle(){
if(this.rightSideNav == false)
{
this.rightSideNav = true;
}
else{
this.rightSideNav = false;
}
}
}
在 header.component.html
中把这段代码:
<app-right-sidenav *ngIf="rightSideNav"></app-right-sidenav>
这将使您的工作变得轻松。
答案 4 :(得分:1)
为了更简单的解决方案,只需使用@ouput() 事件发射器。
在你的父组件中
<mat-sidenav
#sidenav
class="sidenav"
fixedInViewport
[opened]="opened"
[mode]="mode"
>
// catch the emitted output from child component
<childcomponent (sidenav)="sidenav.toggle()"></childcomponent>
....
</mat-sidenav>
子组件
<mat-toolbar>
<div>
<button mat-button (click)="toggle()">
<mat-icon>menu</mat-icon>
</button>
</div>
</mat-toolbar>
子组件.ts
import {Component, EventEmitter, Output} from '@angular/core';
@Component({
selector: 'childcomponent',
templateUrl: './childcomponent.component.html',
styleUrls: ['./childcomponent.component.scss'],
})
export class ChildComponent {
@Output() sidenav: EventEmitter<any> = new EventEmitter();
toggle() {
this.sidenav.emit();
}
}
答案 5 :(得分:0)
只需添加到Eldho的答案中,您就可以禁用动画以获得真正的隐藏效果。
<mat-sidenav #leftbar opened mode="side" class="ng-sidenav" [@.disabled]="true">
答案 6 :(得分:0)
尽管上面的人已经回答了,但是我相信当我自己解决问题时,我的解决方案会更简单。
您需要在中间提供一项服务来支持这两个组件。
比方说,这样的服务是NavService
,下面的代码进入NavService
:
public toggleNav: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
public toggle(): void {
this.toggleNav.next(!this.toggleNav.value);
}
然后,您有一个要从中打开或关闭SideNav
的组件。就我而言,我在Navbar
中创建的按钮为:
button *ngIf="this.loginService.tokenSubject.value" mat-mini-fab color="warn" (click)="onToggle()"><mat-icon>menu</mat-icon></button>
然后在您将为SideNavComponent
创建的SideNav
中,将其放在mat-sidenav
标记中:
[opened]="this.sideNavService.toggleNav.value"
当然,我在该组件的构造函数中将NavService作为sideNavService注入了。
答案 7 :(得分:0)
为了扩展 eldho 服务响应,我在单击时出错 this.sidenav 未定义'我通过确保我的 Side nav 被标记为 #sidenav 以匹配 app.component.ts 文件上的选择器来修复它。
还有 mat-drawer-container 和 mat-drawer 似乎是 sidenav 的新名称
<mat-drawer-container autosize>
<mat-drawer #sidenav class="example-sidenav" mode="side" position="end">
</mat-drawer>
<mat-drawer-content autosize="true">
</mat-drawer-content>
</mat-drawer-container>
app.component.ts
@ViewChild('sidenav') public sidenav: MatSidenav;