从子组件切换#ID

时间:2019-06-21 14:15:15

标签: angular

我正在使用Angular 7,我只需要从SideNav组件内部的TopBar中切换SideNav。

在堆栈和Google上搜索,我发现了很多有关服务组件或奇怪的侦听器的复杂解决方案。

SideNav组件

  <mat-sidenav #sidenav mode="over" role="navigation">
    <mat-nav-list>
        <a mat-list-item routerLink='/first'>Link A</a>
    </mat-nav-list>
  </mat-sidenav>

  <mat-sidenav-content>

    <app-header></app-header>

    <router-outlet></router-outlet>

  </mat-sidenav-content>

AppHeader组件

<mat-toolbar class="labs-header" color="primary" >
  <mat-toolbar-row>
      <button mat-icon-button (click)="sidenav.toggle()">
        <mat-icon>menu</mat-icon>
      </button>
   [...]

如果所有组件代码都直接位于SideNav内部,则可以使用。对于子组件,它显然丢失了#sidenav参考,因此.toggle()将失败。

是否有一种方法可以将mat-sidenav组件绑定并传递给子组件,或者可以在sidenav组件中创建一个切换函数,而不是从子组件中调用它?

2 个答案:

答案 0 :(得分:0)

标题组件应具有一个@Output,它将在您的click事件中发出:

(click)="toggleSidenav.emit()"

在父级中,您可以侦听更改并相应地切换sidenav:

<mat-sidenav #sidenav mode="over" role="navigation">
    <mat-nav-list>
        <a mat-list-item routerLink='/first'>Link A</a>
    </mat-nav-list>
  </mat-sidenav>

  <mat-sidenav-content>

    <app-header (toggleSidenav)="sidenav.toggle()"></app-header>

    <router-outlet></router-outlet>

  </mat-sidenav-content>

这是最干净的方法,因为它不会直接耦合您的组件。如果有人告诉您

  

将sidenav插入标头组件

不要听它,因为它会使组件的可重用性降低。

答案 1 :(得分:0)

在您的AppHeaderComponent.ts中:

@Output() toggle = new EventEmitter();

在您的AppHeaderComponent.html中:

    <mat-toolbar class="labs-header" color="primary" >
     <mat-toolbar-row>
      <button mat-icon-button (click)="toggle.emit()">
        <mat-icon>menu</mat-icon>
      </button>

在您的SideNavComponent.ts中:

    @Viewchild('sideNav') sideNav;

   onToggle(){
     //toggle the sideNav
   }

在您的SideNavComponent.Html中:

<mat-sidenav #sidenav mode="over" role="navigation">
        <mat-nav-list>
            <a mat-list-item routerLink='/first'>Link A</a>
        </mat-nav-list>
      </mat-sidenav>

      <mat-sidenav-content>

        <app-header (toggle)= onToggle()></app-header> // or do it directly in template : sideNav.toggle() instead calling onToggle()

    <router-outlet></router-outlet>

  </mat-sidenav-content>