2017-02-23 2 views
0

Ausgabe:Angular 2 - ein Element zeigen und die andere verbergen,

Ich habe ein Akkordeon aus 4 Elementen, wobei jedes Element Hiddes den Inhalt angezeigt werden soll, wenn ich auf das erste Element klicken, anstatt zu zeigen, bis zum ersten Element Inhalt zeigt es auch die anderen 3.

erwartetes Verhalten:

ich das erste Element klicken möchten und zeigen dann den Inhalt, der zu diesem Element gehört und halten hidding den anderen Inhalt.

Code:

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> 

Bitte, wenn jemand sieht und Antwort, die ich einen Code oder ein Konzept Erklärung schätzen würde, ich weiß, wie diese JS mit jQuery oder Vanille zu tun, aber da es war OOP Ich verstehe die Verwendung von 'this' überhaupt nicht.

Antwort

0

In all diesen Methoden gehört die this zu der Komponente (die Instanz SabiasQueComponent), nicht zu jeder tip.

Es gibt mehrere mögliche Lösungen, ein Vorschlag wird unten gezeigt.

Check demo plunker here

Vorlage:

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

Hinweis drei Änderungen: "{'tips-list__title--active' : isOpen}"-"{'tips-list__title--active' : tip.isOpen}", (click)="showContent()" zu (click)="showContent(tip)" und [hidden]="!isOpen"> zu [hidden]="!tip.isOpen">. Grundsätzlich nehmen wir jetzt die Eigenschaften von jeder Spitze, anstatt von der Komponente.

Komponente:

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() { 
    } 

} 

Im Komponentencode wurde showContent() geändert jetzt ein tip Inhalt angezeigt wird, das zu erhalten. Die get isOpen() und set isOpen() wurden entfernt, da dies nun eine Eigenschaft von jedem tip sein wird. Und closeOthers(openGroup) wurde zugunsten der neuen closeAllTips() entfernt.

+0

Awesome !, sehr klar und ich habe den Code, vielen Dank. –

+0

möchten Sie vielleicht folgende http://angularjs.blogspot.co.uk/2016/04/5-rookie-mistakes-to-avoid-with-angular.html lesen – 72GM

0

In Angular 2 zeigen und verstecken ist nicht wirklich empfohlen/verfügbar mehr. Probieren Sie eine ngIf aus und tun Sie etwas in etwa so! In

(1) einen Index

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

(2) ändern Click-Ereignis und übergeben Index

(click)="showContent(i)" 

(3) eine ngif verwenden, anstatt versteckt

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

(4) Erstellen eines Arrays für die Länge des Spitzenarrays

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

(5) in der Komponente wird Ihre Show Content-Funktion sein, so etwas wie diese

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

this bezieht sich auf die Instanz der Klasse selbst. Bedeutung:

const instance = new SabiasQueComponent() 

Jedes Mal, wenn Sie in der Klasse this beziehen, sind Sie auf die Eigenschaften der Instanz verweisen. Zum Beispiel (Code ungültig ist, aber nur für die Präsentation):

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

Wenn Sie showContent Methode aufrufen, _isOpen der Wert auf der Instanz festgelegt ist, so ist es - in einer Art und Weise - global zu allen Platten, die macht sie öffnen sich gleichzeitig. Stattdessen möchten Sie auf jedem Panel eine isOpen-Eigenschaft haben, in der jeder Status der Panels gespeichert wird. Sie machen es schon beim Schließen von Panels in der closeOthers. Der Teil, der repariert werden muss, ist die Eröffnungslogik.

Es gibt 3 Punkte, die Sie adressieren müssen: 1. Entfernen Sie die _isOpen Eigenschaft der Instanz, da sie nicht benötigt wird. 2. Öffnen Sie das angeklickte Bedienfeld und legen Sie nicht nur die Eigenschaft der Instanz fest. 3.Beziehen Sie sich auf die richtigen Werte in der Vorlage.

Wie für die 1. und 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. 
} 

Jetzt müssen Sie nur isOpen Wert auf die spezifischen Spitze beziehen und die Spitze des Index auf die Öffnungsmethode in Ihrer Vorlage übergeben:

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

Und jetzt sollte es so funktionieren, wie Sie es ursprünglich geplant hatten.

Verwandte Themen