在 angular 4 中切换多个侧边导航
Toggle multiple side navs in angular 4
我的组件结构是
app
--app.component.html
--app.component.ts
-dashboard
--dashboard.component.html
--dashboard.component.ts
-sales
--sales.component.html
--sales.component.ts
-taxreports
--taxreports.component.html
--taxreports.component.ts
-services
--commonservices.ts
我的画面设计
这是我的 app.component.html
代码
<div class="BodyStyle">
<div class="container FirstRowContainer" fxLayout="row" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="container FirstColumnContainer" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="item" fxFlex="16%">
<img class="LogoStyle" src="/src/app/Shared/Images/test.png" height="55" />
</div>
</div>
<div class="container SecondColumnContainer" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="container SecondRowContainer" fxLayout="row" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="container" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="LogoHeading" fxFlex="100%">
<h2 class="restaurantname">Name</h2>
</div>
</div>
<div class="container" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<mat-toolbar class="UserToolBarStyle">
<i class="material-icons UserIconStyle">
person
<button mat-button class="UserButtonStyle">
<h4 class="UserNameStyle">Admin</h4>
</button>
</i>
</mat-toolbar>
</div>
</div>
<div class="container ThirdRowContainer" fxLayout="row" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="container ThirdColumnContainer" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="item" fxFlex="100%">
<mat-toolbar class="ToolBarStyle">
<button mat-button class="ButtonMenu" (click)="btnClick('dashboard');">Dashboard</button>
<button mat-button class="ButtonMenu" (click)="toggleSidenav('sales')">Sales</button>
<button mat-button class="ButtonMenu" (click)="toggleSidenav('taxreports')">Tax Reports</button>
<button mat-button class="ButtonMenu">MIS</button>
<button mat-button class="ButtonMenu">Others</button>
</mat-toolbar>
</div>
</div>
<div class="container FourthColumnContainer" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="item">
<mat-toolbar class="ToolBarStyle">
<i class="glyphicon glyphicon-log-out UserIconStyle1">
<button mat-button class="UserButtonStyle1">
<h4 class="UserNameStyle1">Logout</h4>
</button>
</i>
</mat-toolbar>
</div>
</div>
</div>
</div>
</div>
<div class="placeholder" fxLayout="row" fxLayoutAlign="center" fxLayoutGap="0px" style="margin-top:50px;margin-left:20px;margin-right:20px;">
<div [hidden]="salesDiv"class="item" fxFlex="100%">
<app-tax-reports>
<router-outlet></router-outlet>
</app-tax-reports>
<app-sales>
<router-outlet></router-outlet>
</app-sales>
</div>
<div [hidden]="salesDiv" class="item" fxFlex="100%">
<app-sales>
<router-outlet></router-outlet>
</app-sales>
</div>
</div>
<div class="container FooterContainer" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="item item-4 FooterItem" fxFlex="100%" fxFlexOrder="2">
<footer>
<p class="footer_align">
<span class="FooterText">Powered By</span>
<img class="FooterImage" src="/src/app/Shared/Images/EasyResto.png" />
</p>
</footer>
</div>
</div>
</div>
这是我的 app.component.ts
import { Component, Input } from '@angular/core';
import { HttpservService } from './services/commonservice.service';
import { MatSidenav } from '@angular/material';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
providers: [HttpservService]
})
export class AppComponent {
salesDiv: boolean;
taxDiv: boolean;
constructor(private sidenavService: HttpservService) {
this.salesDiv = true;
this.taxDiv = true;
}
toggleSidenav(div: string) {
if (div == 'sales') {
alert("sales");
this.salesDiv = false;
this.taxDiv = true;
this.sidenavService.toggle();
}
else if (div == 'taxreports') {
alert("taxreports");
this.salesDiv = true;
this.taxDiv = false;
this.sidenavService.toggle();
}
}
}
这是我的销售额component.html
<mat-sidenav-container>
<mat-sidenav #sidenav mode="side" class="mat-elevation-z4">
Sidenav
</matmd-sidenav>
<main>
<ng-content></ng-content>
</main>
</mat-sidenav-container>
这是我的 sales.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { HttpservService } from '../services/commonservice.service';
import { MatSidenav } from '@angular/material';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
@Component({
selector: 'app-sales',
templateUrl: './sales.component.html'
})
export class SalesComponent implements OnInit {
@ViewChild('sidenav') public sidenav: MatSidenav;
constructor(private httpservice: HttpservService, private router: Router) {
}
ngOnInit() {
console.log(this.sidenav);
this.httpservice.setSidenav(this.sidenav);
}
}
在 commonservice.ts 中,我这样调用切换和侧边导航
public setSidenav(sidenav: MatSidenav) {
this.sidenav = sidenav;
}
public toggle(isOpen?: boolean): Promise<MatDrawerToggleResult> {
return this.sidenav.toggle(isOpen);
}
当我点击销售菜单时,侧导航完美切换。但是当我点击税务报告菜单时,侧导航不会切换。它只是在内容区域显示一个空白页。我找不到在 运行 时间内传递给服务的侧边栏。我在销售和税务报告中调用 setSidenav() oninit()。所以发生的事情是,传递的最后一个侧栏被设置为 sidenav 并且只有那个切换。我不明白我在做什么错误。我什至尝试创建 2 个单独的函数作为 setSideNav1() 和 toggle1() 但仍然是同样的问题。
编辑:@Llorenc Pujol Ferriol:我对您的代码做了一些改动。这就是我所做的,而且效果很好。
<div class="placeholder" fxLayout="row" fxLayoutAlign="center" fxLayoutGap="0px" style="margin-top:50px;margin-left:20px;margin-right:20px;">
<div fxFlex="100%">
<router-outlet></router-outlet>
</div>
<mat-sidenav-container>
<mat-sidenav #sidenav align="end" mode="side" class="mat-elevation-z4 side-nav-overflow-hidden">
<app-sales *ngIf="salesDiv">
</app-sales>
</mat-sidenav>
</mat-sidenav-container>
<mat-sidenav-container>
<mat-sidenav #taxnav mode="side" align="end" class="mat-elevation-z4">
<app-tax-reports *ngIf="taxDiv">
</app-tax-reports>
</mat-sidenav>
</mat-sidenav-container>
</div>
但问题是容器占用了大部分宽度,我无法为 matside-nav-container 设置宽度。当我设置它时,它的行为很奇怪。这是它的屏幕截图。
Dashboard and side bar
更新:我通过添加 [ngStyle]="{ 'width.vw': setSalesWidth }"
解决了宽度问题
我在这里看到 两个 问题。第一个问题是显示组件的条件彼此没有区别,当 salesDiv 为真时,两者都被隐藏:
<div [hidden]="salesDiv"class="item" fxFlex="100%">
<app-tax-reports>
<router-outlet></router-outlet>
</app-tax-reports>
<app-sales>
<router-outlet></router-outlet>
</app-sales>
</div>
<div [hidden]="salesDiv" class="item" fxFlex="100%">
<app-sales>
<router-outlet></router-outlet>
</app-sales>
</div>
第二个也是最重要的一点是,您在这里完成的组件架构不是预期的。 Material2 sidenav 组件不希望被销毁并重新初始化,它有相关的动画和当前状态,不是一个好的做法,虽然,没有理由销毁它,只需替换它的内容:
<mat-sidenav-container>
<mat-sidenav #sidenav mode="side" class="mat-elevation-z4">
<app-sales-sidenav *ngIf="salesDiv"></app-sales-sidenav>
<app-taxes-sidenav *ngIf="taxDiv"></app-taxes-sidenav>
</mat-sidenav>
<app-sales *ngIf="salesDiv"></app-sales>
<app-taxes *ngIf="taxDiv"></app-taxes>
</mat-sidenav-container>
这个实现是用*ngIf完成的,它也可以完成动态组件创建。类似的东西:
这会使组件之间的通信也更加困难,因为它是分离的,但最终结果要好得多,它也有助于解耦您的应用程序。
希望对您有所帮助。
我的组件结构是
app
--app.component.html
--app.component.ts
-dashboard
--dashboard.component.html
--dashboard.component.ts
-sales
--sales.component.html
--sales.component.ts
-taxreports
--taxreports.component.html
--taxreports.component.ts
-services
--commonservices.ts
我的画面设计
这是我的 app.component.html
代码<div class="BodyStyle">
<div class="container FirstRowContainer" fxLayout="row" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="container FirstColumnContainer" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="item" fxFlex="16%">
<img class="LogoStyle" src="/src/app/Shared/Images/test.png" height="55" />
</div>
</div>
<div class="container SecondColumnContainer" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="container SecondRowContainer" fxLayout="row" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="container" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="LogoHeading" fxFlex="100%">
<h2 class="restaurantname">Name</h2>
</div>
</div>
<div class="container" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<mat-toolbar class="UserToolBarStyle">
<i class="material-icons UserIconStyle">
person
<button mat-button class="UserButtonStyle">
<h4 class="UserNameStyle">Admin</h4>
</button>
</i>
</mat-toolbar>
</div>
</div>
<div class="container ThirdRowContainer" fxLayout="row" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="container ThirdColumnContainer" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="item" fxFlex="100%">
<mat-toolbar class="ToolBarStyle">
<button mat-button class="ButtonMenu" (click)="btnClick('dashboard');">Dashboard</button>
<button mat-button class="ButtonMenu" (click)="toggleSidenav('sales')">Sales</button>
<button mat-button class="ButtonMenu" (click)="toggleSidenav('taxreports')">Tax Reports</button>
<button mat-button class="ButtonMenu">MIS</button>
<button mat-button class="ButtonMenu">Others</button>
</mat-toolbar>
</div>
</div>
<div class="container FourthColumnContainer" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="item">
<mat-toolbar class="ToolBarStyle">
<i class="glyphicon glyphicon-log-out UserIconStyle1">
<button mat-button class="UserButtonStyle1">
<h4 class="UserNameStyle1">Logout</h4>
</button>
</i>
</mat-toolbar>
</div>
</div>
</div>
</div>
</div>
<div class="placeholder" fxLayout="row" fxLayoutAlign="center" fxLayoutGap="0px" style="margin-top:50px;margin-left:20px;margin-right:20px;">
<div [hidden]="salesDiv"class="item" fxFlex="100%">
<app-tax-reports>
<router-outlet></router-outlet>
</app-tax-reports>
<app-sales>
<router-outlet></router-outlet>
</app-sales>
</div>
<div [hidden]="salesDiv" class="item" fxFlex="100%">
<app-sales>
<router-outlet></router-outlet>
</app-sales>
</div>
</div>
<div class="container FooterContainer" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="0px">
<div class="item item-4 FooterItem" fxFlex="100%" fxFlexOrder="2">
<footer>
<p class="footer_align">
<span class="FooterText">Powered By</span>
<img class="FooterImage" src="/src/app/Shared/Images/EasyResto.png" />
</p>
</footer>
</div>
</div>
</div>
这是我的 app.component.ts
import { Component, Input } from '@angular/core';
import { HttpservService } from './services/commonservice.service';
import { MatSidenav } from '@angular/material';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
providers: [HttpservService]
})
export class AppComponent {
salesDiv: boolean;
taxDiv: boolean;
constructor(private sidenavService: HttpservService) {
this.salesDiv = true;
this.taxDiv = true;
}
toggleSidenav(div: string) {
if (div == 'sales') {
alert("sales");
this.salesDiv = false;
this.taxDiv = true;
this.sidenavService.toggle();
}
else if (div == 'taxreports') {
alert("taxreports");
this.salesDiv = true;
this.taxDiv = false;
this.sidenavService.toggle();
}
}
}
这是我的销售额component.html
<mat-sidenav-container>
<mat-sidenav #sidenav mode="side" class="mat-elevation-z4">
Sidenav
</matmd-sidenav>
<main>
<ng-content></ng-content>
</main>
</mat-sidenav-container>
这是我的 sales.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { HttpservService } from '../services/commonservice.service';
import { MatSidenav } from '@angular/material';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
@Component({
selector: 'app-sales',
templateUrl: './sales.component.html'
})
export class SalesComponent implements OnInit {
@ViewChild('sidenav') public sidenav: MatSidenav;
constructor(private httpservice: HttpservService, private router: Router) {
}
ngOnInit() {
console.log(this.sidenav);
this.httpservice.setSidenav(this.sidenav);
}
}
在 commonservice.ts 中,我这样调用切换和侧边导航
public setSidenav(sidenav: MatSidenav) {
this.sidenav = sidenav;
}
public toggle(isOpen?: boolean): Promise<MatDrawerToggleResult> {
return this.sidenav.toggle(isOpen);
}
当我点击销售菜单时,侧导航完美切换。但是当我点击税务报告菜单时,侧导航不会切换。它只是在内容区域显示一个空白页。我找不到在 运行 时间内传递给服务的侧边栏。我在销售和税务报告中调用 setSidenav() oninit()。所以发生的事情是,传递的最后一个侧栏被设置为 sidenav 并且只有那个切换。我不明白我在做什么错误。我什至尝试创建 2 个单独的函数作为 setSideNav1() 和 toggle1() 但仍然是同样的问题。
编辑:@Llorenc Pujol Ferriol:我对您的代码做了一些改动。这就是我所做的,而且效果很好。
<div class="placeholder" fxLayout="row" fxLayoutAlign="center" fxLayoutGap="0px" style="margin-top:50px;margin-left:20px;margin-right:20px;">
<div fxFlex="100%">
<router-outlet></router-outlet>
</div>
<mat-sidenav-container>
<mat-sidenav #sidenav align="end" mode="side" class="mat-elevation-z4 side-nav-overflow-hidden">
<app-sales *ngIf="salesDiv">
</app-sales>
</mat-sidenav>
</mat-sidenav-container>
<mat-sidenav-container>
<mat-sidenav #taxnav mode="side" align="end" class="mat-elevation-z4">
<app-tax-reports *ngIf="taxDiv">
</app-tax-reports>
</mat-sidenav>
</mat-sidenav-container>
</div>
但问题是容器占用了大部分宽度,我无法为 matside-nav-container 设置宽度。当我设置它时,它的行为很奇怪。这是它的屏幕截图。
Dashboard and side bar
更新:我通过添加 [ngStyle]="{ 'width.vw': setSalesWidth }"
我在这里看到 两个 问题。第一个问题是显示组件的条件彼此没有区别,当 salesDiv 为真时,两者都被隐藏:
<div [hidden]="salesDiv"class="item" fxFlex="100%">
<app-tax-reports>
<router-outlet></router-outlet>
</app-tax-reports>
<app-sales>
<router-outlet></router-outlet>
</app-sales>
</div>
<div [hidden]="salesDiv" class="item" fxFlex="100%">
<app-sales>
<router-outlet></router-outlet>
</app-sales>
</div>
第二个也是最重要的一点是,您在这里完成的组件架构不是预期的。 Material2 sidenav 组件不希望被销毁并重新初始化,它有相关的动画和当前状态,不是一个好的做法,虽然,没有理由销毁它,只需替换它的内容:
<mat-sidenav-container>
<mat-sidenav #sidenav mode="side" class="mat-elevation-z4">
<app-sales-sidenav *ngIf="salesDiv"></app-sales-sidenav>
<app-taxes-sidenav *ngIf="taxDiv"></app-taxes-sidenav>
</mat-sidenav>
<app-sales *ngIf="salesDiv"></app-sales>
<app-taxes *ngIf="taxDiv"></app-taxes>
</mat-sidenav-container>
这个实现是用*ngIf完成的,它也可以完成动态组件创建。类似的东西:
这会使组件之间的通信也更加困难,因为它是分离的,但最终结果要好得多,它也有助于解耦您的应用程序。
希望对您有所帮助。