0

I hope this is a good question and I am not just missing something total simple. I am very new to Angular 2 and I am always into saving code lines and time :)

I want to change the active css class of my tabs (I dont want to use router!) and I ended up with something like this:

activeTab: string;

switchActiveTab(newTab: string) {
  this.activeTab = newTab;
}
<div class="buttonLine">
  <ul class="nav nav-pills">
    <li role="presentation" [ngClass]="{'active': activeTab === 'Example Tab 1'}" (click)="switchActiveTab('Example Tab 1');">
      <a>Example Tab 1</a>
    </li>
    <li role="presentation" [ngClass]="{'active': activeTab === 'Example Tab 2'}" (click)="switchActiveTab('Example Tab 2');">
      <a>Example Tab 2</a>
    </li>
  </ul>
</div>

So I had to declare the string value "Example Tab 1" three times in my HTML. This is pretty annoying, especially when I would have 5 or more tabs here.

Is it possible to avoid reapeating the expression "Example Tab 1" three times in my HTML? Or is it possible to do this kind of stuff in a more elegant way?

3
  • Why dont you want to use routerLinkActive="active"? angular.io/api/router/RouterLinkActive Commented Jun 29, 2017 at 14:43
  • 1
    @FromZeroToHero Because it is not a real routing and I am refactoring old code and implement it with Angular2. So the tabs toggle some webpart visibility in a Sharepoint environment and there should be no URL rewriting or similar stuff. Just change the class names... Commented Jun 29, 2017 at 14:49
  • @ConnorsFan This would be possible, but it should still be declarative when other coders look at the HTML they should see which tab is which. Maybe take the variable from the HTML and insert it into the directive attributes? Is this possible? Commented Jun 29, 2017 at 14:54

1 Answer 1

1

Method 1

To simplify the template code, you can declare the list of tabs in the component class:

public tabList: Array<string> = ["Example Tab 1", "Example Tab 2"];

and generate the li elements with the *ngFor directive:

<li *ngFor="let tab of tabList" [ngClass]="{'active': activeTab === tab}" (click)="switchActiveTab(tab);" role="presentation">
  <a>{{tab}}</a>
</li>

Method 2

To keep the code more declarative, each item could refer to itself with a template reference variable instead of using the tab caption (as illustrated in this plunker):

<div class="buttonLine">
  <ul class="nav nav-pills">
    <li #tab1 [ngClass]="{'active': activeTab === tab1}" (click)="switchActiveTab(tab1);" role="presentation">
      <a>Example Tab 1</a>
    </li>
    <li #tab2 [ngClass]="{'active': activeTab === tab2}" (click)="switchActiveTab(tab2);" role="presentation">
      <a>Example Tab 2</a>
    </li>
  </ul>
</div>

The code would be modified accordingly:

activeTab: HTMLElement;

switchActiveTab(newTab: HTMLElement) {
  this.activeTab = newTab;
}  
Sign up to request clarification or add additional context in comments.

3 Comments

This would be a viable solution, but far from perfect, because I cant give each tab his own class and the readability is also lost. Other coders dont know which tab is which, if they just look at the html.
@FlorianLeitgeb - I added another suggestion to my answer.
I like your second approach. I think those are methods I can live with. Accepted as answer :) Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.