0

我有这个组件StackBliz

模板:

<mat-sidenav-container class="sidenav-container">
  <mat-sidenav #drawer class="sidenav" fixedInViewport
      [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
      [mode]="(isHandset$ | async) ? 'over' : 'side'"
      [opened]="(isHandset$ | async) === false">
    <mat-toolbar>Menu</mat-toolbar>
    <mat-nav-list>
      <a mat-list-item href="#">Link 1</a>
      <a mat-list-item href="#">Link 2</a>
      <a mat-list-item href="#">Link 3</a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <mat-toolbar color="primary">
      <button
        type="button"
        aria-label="Toggle sidenav"
        mat-icon-button
        (click)="drawer.toggle()"
        *ngIf="isHandset$ | async">
        <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
      </button>
      <span>dashboard-app</span>
    </mat-toolbar>
  </mat-sidenav-content>
</mat-sidenav-container>

班级:

export class NavigationComponent {

  isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
    .pipe(
      map(result => result.matches),
      shareReplay()
    );

  constructor(private breakpointObserver: BreakpointObserver) {}

}

我想减少页面上的订阅数量。

我尝试将内容包装到 中ng-container,但这没有用。

首先,我在模板中遇到错误[opened]="isHandset === false",其次是ng-container制动视图,所以即使我离开,也[opened]="(isHandset$ | async) === false"没有显示任何内容

<mat-sidenav-container class="sidenav-container">
    <ng-container *ngIf="isHandset$ | async as isHadset">
      <mat-sidenav #drawer class="sidenav" fixedInViewport
           [attr.role]="isHadset ? 'dialog' : 'navigation'"
           [mode]="isHadset ? 'over' : 'side'"
           [opened]="isHadset === false"> //got an error here saying this condition is always false because isHadset is always 'true'
    ...
           *ngIf="isHadset"
    ...
    
    
      </mat-sidenav-content>
    <ng-container>
</mat-sidenav-container>

任何想法如何解决我上面描述的所有两个问题?

4

1 回答 1

2

使用*ngIf发射boolean并不理想,因为如果值为false. 但是我看到最初你的发射是一个对象。而且由于对象是真实的,您可以忽略映射到布尔值并直接将其与*ngIf.

我还建议将整个容器包装在DOM 中<ng-container>以保留 DOM。

尝试以下

控制器 (*.ts)

import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout';
...

export class NavigationComponent {
  isHandset$: Observable<BreakpointState>;

  constructor(private breakpointObserver: BreakpointObserver) {
    this.isHandset$ = this.breakpointObserver.observe(Breakpoints.Handset);
  }
}

模板 (*.html)

<ng-container *ngIf="(isHandset$ | async) as result">
  <mat-sidenav-container class="sidenav-container">
    <mat-sidenav 
      #drawer 
      class="sidenav" 
      fixedInViewport 
      [attr.role]="(result.matches) ? 'dialog' : 'navigation'"
      [mode]="(result.matches) ? 'over' : 'side'" 
      [opened]="!result.matches"
    >
      <mat-toolbar>Menu</mat-toolbar>
      <mat-nav-list>
        <a mat-list-item href="#">Link 1</a>
        <a mat-list-item href="#">Link 2</a>
        <a mat-list-item href="#">Link 3</a>
      </mat-nav-list>
    </mat-sidenav>
    <mat-sidenav-content>
      <mat-toolbar color="primary">
        <button
          type="button"
          aria-label="Toggle sidenav"
          mat-icon-button
          (click)="drawer.toggle()"
          *ngIf="result.matches"
        >
          <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
        </button>
        <span>dashboard-app</span>
      </mat-toolbar>
    </mat-sidenav-content>
  </mat-sidenav-container>
</ng-container>

我修改了你的Stackblitz

于 2021-07-08T08:21:05.637 回答