typescript - Angular 2 - Visa ett element och dölj de andra,


Problem:

Jag har ett dragspel med 4 element, varje element döljer innehållet som ska visas, när jag klickar på det första elementet, istället för att visa innehållet i det första elementet visas de andra 3 också.

Förväntat beteende:

Jag vill klicka på det första elementet och sedan visa innehållet som tillhör det elementet och fortsätta dölja det andra innehållet.

Kod :

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>

Snälla, om någon ger ett svar skulle jag uppskatta en kod- eller konceptförklaring. Jag vet hur man gör detta med jQuery eller vanlig JS, men eftersom det är OOP förstår jag inte användningen av 'this' alls.

Svar #1

I alla dessa metoder tillhör this komponenten (instansen av SabiasQueComponent), inte varje tip.

Det finns flera möjliga lösningar, ett förslag visas nedan.

Kontrollera demo plunker här

Mall :

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

Observera tre ändringar: "{'tips-list__title--active' : isOpen}" till "{'tips-list__title--active' : tip.isOpen}", (click)="showContent()" till (click)="showContent(tip)", och [hidden]="!isOpen"> till [hidden]="!tip.isOpen">. I princip tar vi nu egenskaperna från varje tip, istället för från komponenten.

Komponent :

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

}

I komponentkoden ändrades showContent() så att den nu tar emot en tip vars innehåll kommer att visas. get isOpen() och set isOpen() togs bort, eftersom det nu kommer att vara en egenskap för varje tip. Och closeOthers(openGroup) togs bort till förmån för den nya closeAllTips().

Svar #2

I Angular 2 rekommenderas/det är egentligen inte längre möjligt att visa och dölja direkt. Prova ett ngIf och gör något ungefär så här!

(1) Lägg till ett index

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

(2) Ändra klickhändelse och skicka index

(click)="showContent(i)"

(3) använd en ngIf istället för hidden

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

(4) skapa en array för längden av tips-arrayen

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

(5) I din komponent kommer din show content-funktion att vara något som detta

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

Relaterade artiklar