我使用带有角度的材质,我想使用viewchild从另一个组件切换Sidenav,但是当我尝试获取mat-sidenav元素时,我得到了未定义。 Heres mi code
sidenav.component.html
<mat-sidenav-container class="example-container">
<mat-sidenav #sidenav class="example-sidenav">
Sidenav content goes here!
</mat-sidenav>
<div class="sidenav-container">
123
</div>
</mat-sidenav-container>
sidenav.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import {MatSidenav} from '@angular/material/sidenav';
@Component({
selector: 'app-sidemenu',
templateUrl: './sidemenu.component.html',
styleUrls: ['./sidemenu.component.scss']
})
export class SidemenuComponent implements OnInit {
@ViewChild('sidenav') sidenav;
constructor() { }
ngOnInit() {
}
openSideNav(){
console.log(this.sidenav)
this.sidenav.open();
}
}
这是我尝试切换sidenav
的组件header.component.ts
import { Component, OnInit } from '@angular/core';
import { SidemenuComponent } from '../sidemenu/sidemenu.component';
@Component({
providers:[SidemenuComponent],
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
constructor(private sm: SidemenuComponent) { }
ngOnInit() {
}
openSideNav(){
this.sm.openSideNav()
}
}
header.component.html
<mat-toolbar color="primary">
<mat-toolbar-row>
<div class="navbar-brand">
<img class="img-fluid" src="./assets/icons/logo_femsa_blanco.png"/>
</div>
<button class="buton-menu" mat-icon-button (click)="openSideNav()">
<img class="img-fluid menu-icon" src="./assets/icons/icons8-menu-filled-50.png"/>
</button>
<span class="toolbar-spacer"></span>
<div class="font-weight-light text-right user-name">
Hola Mundo!
</div>
</mat-toolbar-row>
</mat-toolbar>
希望有人可以提供帮助。我是以棱角分明开始的。抱歉英文不好
答案 0 :(得分:1)
基于您的示例,我创建了Service来管理组件之间的通信。
目标是在代码的任何位置使用API来询问菜单以打开/关闭/切换。
功能步骤:
1 /从任何地方(按钮点击,自定义的东西),你想在你的侧面导航上采取行动。您可以从服务中调用公共函数,例如:this.menuService.open()
2 /如果需要,您的服务将通过Observable接下来的新菜单状态。
3 /管理sidenav的组件将订阅此状态的任何更改,并在需要时执行“打开/关闭”。
状态由主题和内部服务标志管理
export class MenuService {
private menuIsOpen$ : Subject<boolean>;
private menuIsOpen: boolean = false;
constructor() {
this.menuIsOpen$ = new Subject<boolean>();
}
/**
* If menu is open, let close it
**/
public open() {
if(!this.menuIsOpen) {
this.menuIsOpen = true;
this.menuIsOpen$.next(false);
}
}
/**
* Both silence open and close is use by navbar output, to silence switch internal flag.
**/
public silenceOpen() {
this.menuIsOpen = true;
}
public silenceClose() {
this.menuIsOpen = false;
}
/**
* If menu is close, let open it
**/
public close() {
if(this.menuIsOpen) {
this.menuIsOpen = false;
this.menuIsOpen$.next(false);
}
}
public toggle() {
this.menuIsOpen = !this.menuIsOpen;
this.menuIsOpen$.next(this.menuIsOpen);
}
public asObservable()
{
return this.menuIsOpen$.asObservable();
}
}
然后你的组件嵌入了sidenav:
export class SidemenuComponent implements OnInit {
@ViewChild('sidenav') sidenav: MatSidenav;
constructor(private menuService: MenuService)
{
}
ngOnInit() {
/**
When you reveive order to open / close sidenav.
**/
this.menuService.asObservable().subscribe((isOpen: boolean) => {
if(isOpen) {
this.sidenav.close();
}
else{
this.sidenav.open();
}
});
}
onOpenedChange() {
this.menuService.silenceOpen();
}
onClosedChange() {
this.menuService.silenceClose();
}
}
Html方面: