根据进度突出显示侧边栏项目

Highlight the sidebar item according the progress

我有一个侧边栏来显示工作进度。现在我有三个阶段。

一开始项目还没有开始,所以我希望所有侧边栏项目都是灰色的。我希望当前阶段基于先前阶段的完成。 在右侧有三个按钮。这是逻辑。

  1. 正在进行第 1 阶段。当我处理阶段 1 时,阶段 1 侧边栏项目处于活动状态并且颜色为绿色。第 2 阶段和第 3 阶段项目仍处于非活动状态。
  2. 正在进行第 2 阶段。当我单击第 1 阶段完成按钮时,我们进入第 2 阶段,第 2 阶段显示为绿色,第 1 阶段仍处于活动状态,但没有颜色。
  3. 正在进行第 3 阶段。当我单击第 2 阶段完成按钮时,我们进入第 3 阶段,第 3 阶段显示为绿色,第 1 阶段和第 2 阶段处于活动状态,但只是没有颜色。
  4. 当我们进入下一阶段时,前一阶段项目的边框可见。

我的ts代码:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-sidenav',
  templateUrl: './sidenav.component.html',
  styleUrls: ['./sidenav.component.css']
})
export class SidenavComponent implements OnInit {

  sidenavWidth = 10;
  ngStyle: string;
  active1: boolean;
  active2: boolean;
  active3: boolean;
  constructor() {

  }

  ngOnInit() {
    this.active1 = false;
    this.active2 = false;
    this.active3 = false;
  }
  submit1() {
    this.active1 = true;
    this.active2 = false;
    this.active3 = false;
    console.log('1');
  }
  submit2() {
    this.active1 = true;
    this.active2 = true;
    this.active3 = false;
    console.log('2');
  }
  submit3() {
    this.active1 = true;
    this.active2 = true;
    this.active3 = true;
    console.log('3');
  }
}

我的html:

    <mat-sidenav-container fullscreen>
  <mat-sidenav #sidenav  mode="side" class="example-sidenav" [ngStyle]="{ 'width.em': sidenavWidth }" opened="true">
    <div class="logomain">Project progress</div>
    <mat-nav-list>
      <mat-list-item routerLink="1" [routerLinkActive]="[active1]" >
        <div fxFlex="10"></div>
        <div *ngIf="sidenavWidth > 6" class="sidenav-item">
          <h5 class="lead">Phase 1</h5>
        </div>
      </mat-list-item>

      <mat-list-item routerLink="2" [routerLinkActive]="[active2]">
        <div fxFlex="10"></div>
        <div *ngIf="sidenavWidth > 6" class="sidenav-item">
          <h5 class="lead">Phase 2</h5>
        </div>
      </mat-list-item>

      <mat-list-item routerLink="3" [routerLinkActive]="[active3]">
        <div fxFlex="10"></div>
        <div *ngIf="sidenavWidth > 6" class="sidenav-item">
          <h5 class="lead">Phase 3</h5>
        </div>
      </mat-list-item>
    </mat-nav-list>

  </mat-sidenav>

  <!-- <div class="example-sidenav-content">
    <router-outlet></router-outlet>
    
  </div> -->
  <br><br><br>
 <section>
  <br>
  <div class="example-button-row">
    <button mat-raised-button color="primary" (click) ="submit1()">Phase 1 completed</button>
   </div>
</section>
<mat-divider></mat-divider>
<br>
<section>
    <br>
    <div class="example-button-row">
      <button mat-raised-button color="primary" (click) = "submit2()">Phase 2 completed</button>
    </div>
</section>
<br>
.<section>
    <br>
    <div class="example-button-row">
      <button mat-raised-button color="primary" (click) = "submit3()">Phase 3 completed</button>
    </div>
</section>
<br>
</mat-sidenav-container>

这里是 stackblize example.

我的问题。当我单击按钮时,边栏项目不会因条件而变灰。我也不知道如何将绿色应用到工作阶段。

最后我有很多项目而不是示例中的 3 个项目。我不想在点击事件中手动设置布尔值。

更新:

正确的可编辑 stackblitz link https://stackblitz.com/edit/angular-material-with-angular-sidenav-etrylt

<button
    mat-raised-button
    color="primary"
    [ngClass]="
      phase.active1 === true
        ? 'active'
        : completedPhase.indexOf('active1') > -1
        ? 'pre-active'
        : ''
    "
  >
    Phase 1 completed
  </button>

  <button
    mat-raised-button
    color="primary"
    [ngClass]="
      phase.active2 === true ? 'active' : completedPhase.indexOf('active2') > -1
        ? 'pre-active'
        : ''
    "
  >
    Phase 2 completed
  </button>

看起来您只需要一个简单的结构来表示您的阶段,并用 属性 指示它是否已完成。

interface Phase {
    id: number;
    name: string;
    isComplete: boolean;
}

然后,当您单击一个按钮时,切换 isComplete 属性。

您可以定义一个 Phase 对象数组并使用 *ngFor 在您的模板中重复它们。这将防止您的模板在您添加更多阶段时增长。

sidebar.component.ts:

  public phases = [
    { id: 1, name: "Phase 1", isComplete: false },
    { id: 2, name: "Phase 2", isComplete: false },
    { id: 3, name: "Phase 3", isComplete: false }
  ];

sidebar.component.html:

<mat-nav-list>
  <mat-list-item *ngFor="let phase of phases">
      <h5>{{ phase.name }}</h5>
  </mat-list-item>
</mat-nav-list>

<section *ngFor="let phase of phases">
    <button
      (click)="togglePhaseComplete(phase)"
      [disabled]="phase.isComplete"
    >
      {{ phase.name }} completed!
    </button>
  </div>
</section>

然后,您可以在模板中使用 isComplete 属性 来禁用已完成阶段的按钮:

[disabled]="phase.isComplete"

您还可以制作一个小辅助函数来确定某个阶段是否处于活动状态,以便显示您的绿色背景颜色:

public isActive(phase: Phase) {
    // the first incomplete phase found is active
    const activePhase = this.phases.find(p => !p.isComplete);
    return phase.id === activePhase?.id;
}

然后只需将 [class.green]="isActive(phase)" 添加到您的 mat-list-item假设您在 css[=50= 中定义了一个名为“green”的 class ]).

这是一个有效的 StackBlitz

现在,禁用尚未激活的阶段的导航项需要更多的工作,因为 mat-list-item 没有像按钮这样的 disabled 属性确实如此,所以这样的事情是行不通的:

<mat-list-item *ngFor="let phase of phases" 
               [disabled]="!isActive(phase) && !phase.isComplete"
>

但是,如 中所述,您可以创建 css class 来禁用鼠标事件并将项目显示为已禁用,因此代码如下所示:

<mat-list-item *ngFor="let phase of phases" 
               [class.disabled]="!isActive(phase) && !phase.isComplete"
>