-1

I have an iterable which is being used in an ngFor

<div *ngFor="let item in items">{{item.name}}</div>

I also have a method getNumberOfSpecialItems() which returns the number of special items, say N.

I would like to apply a class "special" to the first N divs in the ngFor. What is the best way to do this?

NCoder
  • 39
  • 7
  • 2
    What part of that are you stuck on, exactly? What would *"best"* mean to you? [The docs](https://angular.io/docs) show you how to: get the index in `ngFor`; dynamically add or remove a class; call methods from the template; etc. Please give a [mcve] of your implementation, outlining a specific problem. – jonrsharpe Jan 14 '18 at 17:06

3 Answers3

1

Well, I think that it should be done like this:

<div *ngFor="let item in items; let i = index" [ngClass]="{'special': i < getNumberOfSpecialItems()}">{{item.name}}</div>

where i - item's index in the list.

Probably, it would be better to assign getNumberOfSpecialItems() to a variable in the controller and to use this variable, because NgClass is a watcher and in the case above function will be invoked every iteration.

Update: There are several ways in Angular 5 to bind class parameter conditionally which you can find here.

Alexandr
  • 95
  • 8
  • 1
    One downside to this approach is the fact that the POJO passed to the `ngClass` directive will be created in every change detection cycle. Because of this, the `ngClass` receives a "new" input object (different object reference) meaning that the `
    ` node in the DOM will be repainted every time. TL;DR; perfomance is bad
    – Jota.Toledo Jan 14 '18 at 18:30
0

I normally prefer property binding over the NgClass directive when setting a class depends on a boolean evaluation:

<div *ngFor="let item in items; index as i"
      [class.special]="i < getNumberOfSpecialItems()">
{{item.name}}
</div>

In the template, i is the index value exposed by the NgForOf directive

Jota.Toledo
  • 27,293
  • 11
  • 59
  • 73
-1

I used this Approach:

<ng-container *ngFor="let item of items; index as count">
    <ngcontainer *ngIf="count<getNumberOfSpecialItems() else simple">
      <div ngClass="special"> {{item.name}} </div>
</ng-container>
   <ng-template #simple>
      <div> {{item.name}} </div>
   <ng-template>
</ng-container>`

Happy coding :)

Vikas
  • 11,859
  • 7
  • 45
  • 69
  • isn't that a little bit overcomplicated? – Jota.Toledo Jan 14 '18 at 18:11
  • why would you say that on gods green earth?? the solution uses if else clause how come it's overcomplicated.? @Jota. Toledo – Vikas Jan 14 '18 at 18:24
  • If its not obvious to you, I guess its not worth explaining – Jota.Toledo Jan 14 '18 at 18:32
  • I just gave an alternate solution. – Vikas Jan 14 '18 at 18:34
  • Yeah its an alternative, but not a good one IMO. Whats the purpose of using ngClass over simply class in this case, if the class to be aplied is constant? What if instead of rendering a simple div, OP now wants to render a larger templare. Would he really want to write that 2 times, with only a small difference between the both? I dont think so – Jota.Toledo Jan 15 '18 at 07:34