Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Style in ngFor loop

Tags:

angular

I have an app which I'm developing in Angular 2 (RC1). The menu is need to be created from the database. Data is delivered via Web Api in JSON form. I would like to build menu from the data recursively, to be sure that depth of the menu is not an issue.

The problem is when I'm want to add class on particular row of ngFor loop, and the class is added to all rows instead of just one I want to.

The code is looking something like this:

sidenav.component.ts

import { Component, Input } from '@angular/core';
import { IMenu } from '../../../shared/models/menu.interface';
import { MenuComponent } from './menu.component';

@Component({
    moduleId: module.id,
    selector: 'sidenav',
    templateUrl: 'sidenav.component.html',
    directives: [MenuComponent]
})
export class SidenavComponent {
    @Input() menu: IMeni[]
}

sidenav.component.html

...
<menu-view [menu]="menu"></menu-view>
...

menu.component.ts

import { Component, Input } from '@angular/core';
import { IMenu } from '../../../shared/models/menu.interface';
@Component({
    moduleId: module.id,
    selector: 'menu-view',
    templateUrl: 'menu.component.html',
    directives: [MenuComponent]
})
export class MenuComponent {
    isSelected: boolean = false;
    @Input() meni: IMeni[];

    onSelect(): void {
        this.isSelected = !this.isSelected;
    }
}

menu.component.html

<ul>
     <li  *ngFor="let item of menu; let frst=first"
           class="menu-list" 
           [ngClass]="{'active': 'isSelected', 'active': 'frst'}">

        <a [routerLink]="[item.uri]" (click)="onSelect()" > {{item.name}}</a>

        <meni-view [menu]="item.children"></meni-view>

     </li>
</ul>

So, when I click on parent all parents become active, not only that particular one, what will be satisfying behaviour. What I do wrong?

like image 638
Igor Ilić Avatar asked May 31 '16 12:05

Igor Ilić


2 Answers

It seems like your variable isSelected is shared across the list. Change the variable to track the index instead.

export class App {
    menu = [{name: "Item 1", url: "/item1"}, {name: "Item 2", url: "/item2"},{name: "Item 3", url: "/item3"}];
    selectedIdx = 0;

    selectItem(index):void {
        this.selectedIdx = index;
    }
}

render it with

<li  *ngFor="let item of menu;let i = index"
   class="menu-list" [ngClass]="{'active': selectedIdx == i}">
   <a (click)="selectItem(i)"> {{item.name}}</a>
</li>

Working http://plnkr.co/edit/7aDLNnhS8MQ1mJVfhGRR

like image 120
zlace Avatar answered Nov 29 '22 05:11

zlace


There are some redundant '. I guess you want to bind the value of the property isSelected not the 'isSelected' string (same with frst)

 <li  *ngFor="let item of menu; let frst=first"
       class="menu-list" 
       [ngClass]="{'active': isSelected, 'active': frst}">
like image 22
Günter Zöchbauer Avatar answered Nov 29 '22 05:11

Günter Zöchbauer