2016-05-31 60 views
7

我有一個應用程序,我正在Angular 2(RC1)中開發。菜單需要從數據庫創建。數據通過Web Api以JSON形式提供。我想從數據遞歸地構建菜單,以確保菜單的深度不是問題。ngFor循環中的樣式

問題是,當我想要在ngFor循環的特定行上添加類時,該類被添加到所有行而不是我想要的。

的代碼看起來像這樣:

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> 

所以,當我點擊父所有的父母變得活躍,不僅如此特別的一個,這將是令人滿意的行爲。我做錯了什麼?

+0

你是什麼意思「,點擊父所有的父母都成了使它活性」?如果這是「點擊父母,所有'MenuComponent'變得活躍」? –

+0

構建菜單時,它提供了父項和子項的層次結構。假設菜單的模型是:'id:number; parentId:number; name:string;兒童:IMenu [];'。所以,當我點擊菜單項的父實例時,我打開了所有父菜單的實例。想要的行爲應該是,當我點擊父實例時,它會打開,或者說只給予正確的類,以阻止所選父項的子項。 –

回答

10

好像你的變量isSelected跨列表共享。改變變量來跟蹤索引。

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; 
    } 
} 

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

工作 http://plnkr.co/edit/7aDLNnhS8MQ1mJVfhGRR

+0

謝謝,這正是我想要的。 –

+0

謝謝像天堂般的工作:) –

+0

工程就像一個魅力!很好的答案! – fauverism

3

還有一些多餘的'。我猜你要綁定的屬性isSelected不是'isSelected'字符串的值(與frst相同)

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

謝謝,但我沒有用'''試過,結果相同。我用'''繼續編碼,因爲它使我有可能包含其他邏輯問題,如:[ngClass] =「{'nav-stacked':'item.depth === 1'}」'。 –

+1

爲什麼要用'''比'沒有'更好? –

+0

特定的語法('[ngClass] =「{'nav-stacked':item.depth === 1}」')不起作用。 –

2

我得到了一個解決方案(這很容易),當您收到JSON數據並將其保存在一個變量(你的情況叫它menu)加到menu一個叫做類的新字段並將其渲染到模板中!

例子:

@Input() menu: IMenu[]; 
getMenu(){ 
    this.http.get(url).then(data => { 
    this.menu = data; 
    for(let i = 0; i < this.menu.length; i++) { 
     if(i == indexOfWantedElement){ 
     this.menu[i].classes = "myClass"; 
     continue; 
     } 
     this.menu[i].classes = ""; // others will have no classes 
    } 
    } 
} 

,並在模板中,你可以使它easliy

<ul> 
    <li *ngFor="let item of menu;" class="menu-list {{ item.classes }}"> 
    <a [routerLink]="[item.uri]" (click)="onSelect()" >{{item.name}}</a> 
    <meni-view [menu]="item.children"></meni-view> 
    </li> 
</ul> 
+0

謝謝!我會肯定的嘗試。不過,我仍然會在沒有循環的情況下尋找答案。 –

+0

@IgorIlić*** zaclerv ***的答案,你**驗證**是偉大的,但它只是在點擊工作!我的答案會將該類添加到多個元素,而不需要單擊事件,這就是差異!無論如何祝你好運傢伙:) –

0

添加#clickState你行的*ngFor

<row #clickState> 
    <i class="icon-cloud-download" 
     *ngIf="!clickState.clicked" 
     (click)="clickState.clicked=true"></i> 
    <i class="fa fa-spinner" 
     *ngIf="clickState.clicked 
     (click)="clickState.clicked=false"></i> 
</row>