2017-02-23 66 views
0

問題:角2 - 顯示的元素,並隱藏其他

我有4種元素的手風琴,每個元件hiddes內容要被顯示,當我點擊到第一元件,而不是顯示第一個元素的內容顯示其他3個。

預期的行爲:

我想點擊的第一個元素,然後顯示屬於該元素的含量,並保持hidding其他內容。

代碼:

import { Component, OnInit } from '@angular/core'; 

@Component({ 
    selector: 'app-sabias-que', 
    templateUrl: './sabias-que.component.html', 
    styleUrls: ['./sabias-que.component.scss'] 
}) 
export class SabiasQueComponent implements OnInit { 

    private _isOpen : boolean = false; 
    private tips : Array<any> = [ 
    { 
     heading: 'Title 1', 
     content: 'Content to be displayed' 
    }, 
    { 
     heading: 'Title 1', 
     content: 'Content to be displayed' 
    }, 
    { 
     heading: 'Title 1', 
     content: 'Content to be displayed' 
    }, 
    { 
     heading: 'Title 1', 
     content: 'Content to be displayed' 
    } 
    ] 

    closeOthers(openGroup): void { 
    this.tips.forEach((tip) => { 
     if (tip !== openGroup) { 
     tip.isOpen = false; 
     } 
    }); 
    } 

    set isOpen(value: boolean) { 
    debugger; 
    this._isOpen = value; 
    if (value) { 
     this.closeOthers(this); 
    } 
    } 

    get isOpen() { 
    return this._isOpen; 
    } 



    constructor() { } 

    ngOnInit() { 
    } 

    showContent(): void { 
    this.isOpen = !this.isOpen; 
    } 

} 

HTML:

<ul class="tips-list"> 
    <li *ngFor="let tip of tips"> 
    <h3 class="tips-list__title" 
     [ngClass]="{'tips-list__title--active' : isOpen}" (click)="showContent()"> 
     {{ tip.heading }}  
    </h3> 
    <p class="tips-list__answer" [hidden]="!isOpen"> 
     {{ tip.content }} 
    </p> 
    </li> 
</ul> 

請,如果有人提供和答案,我將不勝感激代碼或概念的解釋,我知道如何使用jQuery或香草JS但由於這樣做它一直是OOP我根本不明白使用'this'

回答

0

在所有這些方法中,this屬於組件(SabiasQueComponent的實例),而不是每個tip

有幾種可能的解決方案,其中一個建議如下所示。

Check demo plunker here

模板:

<ul class="tips-list"> 
    <li *ngFor="let tip of tips"> 
    <h3 class="tips-list__title" 
     [ngClass]="{'tips-list__title--active' : tip.isOpen}" (click)="showContent(tip)"> 
     {{ tip.heading }}  
    </h3> 
    <p class="tips-list__answer" [hidden]="!tip.isOpen"> 
     {{ tip.content }} 
    </p> 
    </li> 
</ul> 

注意三個轉變:"{'tips-list__title--active' : isOpen}""{'tips-list__title--active' : tip.isOpen}"(click)="showContent()"(click)="showContent(tip)",並[hidden]="!isOpen">[hidden]="!tip.isOpen">。基本上我們現在從每個提示中取出屬性,而不是來自組件。

組件:

export class SabiasQueComponent implements OnInit { 

    private _isOpen : boolean = false; 
    private tips : Array<any> = [ 
    // all the same 
    ] 

    closeAllTips(): void { 
    this.tips.forEach((tip) => { 
     tip.isOpen = false; 
    }); 
    } 

    showContent(tip) { 
    if (!tip.isOpen) { 
     this.closeAllTips(); 
    } 
    tip.isOpen = !tip.isOpen; 
    } 

    constructor() { } 

    ngOnInit() { 
    } 

} 

在分量代碼,showContent()變更爲現在接收tip其內容將被顯示。 get isOpen()set isOpen()被刪除,因爲這將是每個tip現在的屬性。並且closeOthers(openGroup)已被刪除,以支持新的closeAllTips()

+0

太棒了!非常清楚,我收到了代碼,非常感謝。 –

+0

你可能想閱讀以下內容http://angularjs.blogspot.co.uk/2016/04/5-rookie-mistakes-to-avoid-with-angular.html – 72GM

0

在角2顯示和隱藏不是真的推薦/可用了。試試ngIf並做一些粗略的操作!

(1)添加一個索引

<li *ngFor="let tip of tips;let i=index"> 

(2)改變點擊事件,並通過索引

(click)="showContent(i)" 

(3)使用一個ngif代替隱

<p class="tips-list__answer" *ngIf="showTips[i]"> 

( 4)創建一個陣列長度的提示陣列

showTips = [false, false, false, false, false....]; 

(5)在你的組件你的節目內容功能將是這樣的

showContent(index){ 
    for(i=0;i < this.tips.length; i++){ 
     this.showTips[i] = false; 
    } 
    this.showTips[index] = true; 
} 
0

this指的是類本身的實例。含義:

const instance = new SabiasQueComponent() 

每當你在課堂上是指this,你指的是該實例的屬性。例如(代碼是無效的,但只是爲了演示):

this.tips === instance.tips 
this._isOpen === instance._isOpen 

每當你調用showContent方法,價值_isOpen設置上的實例,所以這是 - 在某種程度上 - 全球所有面板,這使得他們同時打開。你想要的是在每個面板上都有一個isOpen屬性,它將存儲每個面板的狀態。在關閉closeOthers中的面板時,您已經這樣做了。需要修復的部分是開放邏輯。

有3點需要注意: 1.刪除實例的_isOpen屬性,因爲它不是必需的。 2.打開點擊的面板,不只是設置實例的屬性。 3。請參閱模板中的適當值。

至於1號和2號:

export class SabiasQueComponent implements OnInit { 
    // Removed _isOpen. 

    // Store the open state in panels 
    private tips : Array<any> = [ 
     { 
      heading: 'Title 1, 
      content: 'content', 
      isOpen: false // Stored state. 
     }, 
     // Same for others... 
    ] 

    // Method needs to know which tab to open, so we're providing the index. Named it "toggleContent" since we're actually toggling, not just showing. 
    toggleContent(index: number) { 
      this.tips[index].isOpen = !this.tips[index].isOpen 
      // After toggling, close other tabs. 
      this.closeOthersExcept(index) 
    } 

    // You pretty much already have this. 
    this.closeOthersExcept(index: number) { 
     this.tips.forEach((tip, tipIndex) => { 
      if (index !== tipIndex) { 
       tip.isOpen = false 
      } 
     }) 
    } 

    // No other methods/setters are required. 
} 

現在你只需要參考具體的尖端的isOpen價值和尖端的指數傳遞到您的模板開啓方法:

<ul class="tips-list"> 
    <!-- Get the index value from the ngFor. --> 
    <li *ngFor="let tip of tips; let index = index"> 
    <!-- 1. Refer to the tip.isOpen instead of the "global" isOpen when adding a class. --> 
    <!-- 2. Pass the index to the opening method. --> 
    <h3 class="tips-list__title" 
     [ngClass]="{'tips-list__title--active' : tip.isOpen (click)="showContent(index)"> 
     {{ tip.heading }}  
    </h3> 
    <p class="tips-list__answer" [hidden]="!tip.isOpen"> 
     {{ tip.content }} 
    </p> 
    </li> 
</ul> 

現在它應該按照您最初的預期工作。