Viewchild未定义材质角度matsidenav

时间:2018-03-27 18:37:06

标签: javascript angular angular-material

我使用带有角度的材质,我想使用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>

希望有人可以提供帮助。我是以棱角分明开始的。抱歉英文不好

1 个答案:

答案 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方面:     

示例:https://stackblitz.com/edit/angular-2faa8z