web-dev-qa-db-ja.com

angularの折りたたみアコーディオン

angularアプリケーションでJavaScriptを使用して折りたたみ可能なdivを作成するためにアコーディオンを作成しています。

Parent Oneのボタンやその他の親の名前をクリックしても開かない場合は、.

Html

<div *ngFor="let item of data">
  <button class="accordion"> {{item.parentName}} </button>
  <div class="panel" *ngFor="let child of item.childProperties">
  <p> {{child.propertyName}} </p>
</div>
</div>

Ts

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  data: any =
    [
      {
        "parentName": "Parent One",
        "childProperties":
          [
            { "propertyName": "Property One" },
            { "propertyName": "Property Two" }
          ]
      },
      {
        "parentName": "Parent Two",
        "childProperties":
          [
            { "propertyName": "Property Three" },
            { "propertyName": "Property Four" },
            { "propertyName": "Property Five" },
          ]
      },
      {
        "parentName": "Parent Three",
        "childProperties":
          [
            { "propertyName": "Property Six" },
            { "propertyName": "Property Seven" },
            { "propertyName": "Property Eight" },
          ]
      }
    ]

  ngOnInit() {
    var acc = document.getElementsByClassName("accordion");
    var i;

    for (i = 0; i < acc.length; i++) {
      acc[i].addEventListener("click", function () {
        this.classList.toggle("active");
        var panel = this.nextElementSibling;
        if (panel.style.maxHeight) {
          panel.style.maxHeight = null;
        } else {
          panel.style.maxHeight = panel.scrollHeight + "px";
        }
      });
    }
  }

}

注:私はangularで新しいので、javascriptの方法で作成しています。 pure angular and TypeScript。)を使用した結果.

動作していますstackblitzhttps://stackblitz.com/edit/angular-lp3riw

デモでは、親ボタンが表示されていることを確認できますが、ボタンをクリックしても展開されません。

静的な値を使用して、以下の折りたたみ可能なボタンもリストされています。

angularとTypeScriptを使用して(サードパーティまたはjqueryなしで))指定されたstackblitz静的値のように折りたたみ可能なアコーディオンを作成する方法。

5
Maniraj Murugan

関数をngAfterViewInitではなくngOnInitに保持します。更新された stackblitz を参照してください

問題は、ngOnInitではビューが完全にペイントされておらず、関数をバインドするすべての要素を取得できないことです。

ngAfterViewInit() {
    var acc = document.getElementsByClassName("accordion");
    var i;

    for (i = 0; i < acc.length; i++) {
      acc[i].addEventListener("click", function () {
        this.classList.toggle("active");
        var panel = this.nextElementSibling;
        if (panel.style.maxHeight) {
          panel.style.maxHeight = null;
        } else {
          panel.style.maxHeight = panel.scrollHeight + "px";
        }
      });
    }
  }

angularを使用して、以下のようにします。

ボタンのクリック関数を維持し、プロパティisActiveを対応する配列要素にバインドします。次に、isActiveの値がtrue/falseかどうかに基づいて、アコーディオンを表示/非表示にします。

<div *ngFor="let item of data;let i = index;">
  <button class="accordion" (click)="toggleAccordian($event, i)"> {{item.parentName}} </button>
  <div class="panel" *ngFor="let child of item.childProperties" hide="!item.isActive">
  <p> {{child.propertyName}} </p>
</div>
</div>


toggleAccordian(event, index) {
      var element = event.target;
      element.classList.toggle("active");
      if(this.data[index].isActive) {
        this.data[index].isActive = false;
      } else {
        this.data[index].isActive = true;
      }      
      var panel = element.nextElementSibling;
      if (panel.style.maxHeight) {
        panel.style.maxHeight = null;
      } else {
        panel.style.maxHeight = panel.scrollHeight + "px";
      }
  }
3
Nandita Sharma