Angular 2 ngClass function

蓝咒 提交于 2020-01-24 12:58:07

问题


Hi I was in the midst of creating a wizard/step component. How can I use the ngClass to return css classes based on ->?

I have 5 steps, let's say the user is in the 3rd step. All the previous steps should return a css class named active and the current step (step 3) returns css class active and all the steps after step 3 should return inactive css class.

<div class="step actived">
                    <span [ngClass]="displayActiveness()">Step 1
                    </span>
                </div>
                <div class="divider"></div>
                <div class="step" [ngClass]="displayActiveness()">
                    <span>Step 2
                    </span>
                </div>
.....

TS:

displayActiveness(status) {
        if (this.statusSelected === 'step3') {
            return 'active';
        } else if (
        this.statusSelected === 'step4' || this.statusSelected === 'step5'){
            return 'inactive';
        }
        else if (
            this.statusSelected === 'step1' || this.statusSelected === 'step2'){
                return 'actived';
            }
    }

I am stuck. Can someone please help me on this. Thanks in advance.


回答1:


Why not set your statusSelected to number and it would be easy to manage?

TS:

statusSelected: number = 1; //step 1 by default
....
displayActiveness(status) {
    if (this.statusSelected === status) {
      return 'active';
    }
    if (this.statusSelected > status) {
      return 'actived';
    }
    if (this.statusSelected < status) {
      return 'inactive';
    }
}

HTMl:

<div class="step"  [ngClass]="displayActiveness(1)">
    <span>Step 1</span>
</div>
<div class="divider"></div>
<div class="step" [ngClass]="displayActiveness(2)">
    <span>Step 2</span>
</div>

with this, next step could be only:

nextStep() {
    this.statusSelected++;
}



回答2:


Alternatively, You can iterate over loop and set active class to your step like this -

<div class="step" [ngClass]='{"active" : activeClassList[0]}'>
  <span>Step 0</span>
</div>
<div class="step" [ngClass]='{"active" : activeClassList[1]}'>
  <span>Step 1</span>
</div>
<div class="step" [ngClass]='{"active" : activeClassList[2]}'>
  <span>Step 2</span>
</div>
<div class="step" [ngClass]='{"active" : activeClassList[3]}'>
  <span>Step 3</span>
</div>
<div class="step" [ngClass]='{"active" : activeClassList[4]}'>
  <span>Step 4</span>
</div>
<div class="step" [ngClass]='{"active" : activeClassList[5]}'>
  <span>Step 5</span>
</div>

settingActiveClass() {
     for(let i=0; i < this.userLevel; i++) {
       this.activeClassList[i] = 'active';
     }
   }

working example




回答3:


Check the following example.

component.html

<ul>
    <li *ngFor="let step of steps; let i = index">
        <span class="step" [ngClass]="displayActiveness(i)">
            {{step}} 
        </span>
        <button (click)="chooseStep(i)">Click me</button>
    </li>
</ul>

component.ts

export class AppComponent  {
  name = 'Angular 6';
  currentStep = 0;
  steps = ['step1', 'step2', 'step3', 'step4', 'step5'];

  chooseStep(index) {
    this.currentStep = index;
  }

  displayActiveness(index) {
    console.log('displayActiveness called')
    if (index > this.currentStep) {
      return 'inactive';
    } else {
      return 'active';
    }
  }

}

When you check the console, you'll see displayActiveness method gets called 10 times when you click on Click me button. This is because of angular change detection mechanism. When something happens to trigger change detection, angular will go through your template and call everything. So, generally it's not a good idea to call functions within templates. But, let's say you absolutely need to do so. Then, you can use pipes.

Check this second example

In this example, I moved the logic of displayActiveness method to a Pipe, so that it only gets executed when the inputs change. It may not differ much in your example but think of a much more complicated method. You would not want angular to call your complicated method every time user does something.

active.pipe.ts

@Pipe({
  name: 'activePipe'
})
export class ActivePipe implements PipeTransform {
  transform(index, currentStep) {
    console.log('pipe called')
    if (index > currentStep) {
      return 'inactive';
    } else {
      return 'active';
    }
  }
}

Changing ngClass to following

<span class="step" [ngClass]="i | activePipe: currentStep">
    {{step}} 
</span>


来源:https://stackoverflow.com/questions/50226800/angular-2-ngclass-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!