2017-02-08 7 views
0

私はシンプルなアコーディオン角度2の単純なアコーディオンを作成するにはどうすればよいですか?

(function() { 

    $('dl.accordion').on('click', 'dt', function() { 
     this_= $(this); 
     this_ 
      .addClass("selected") 
      .next() 
       .slideDown(200) 
       .siblings('dd') 
        .slideUp(200); 
     this_.siblings() 
      .removeClass("selected") 

    }); 
})(); 

そしてこのHTML

<dl class="accordion"> 
    <dt>What are your hours?</dt> 
    <dd>We are open 24/7.</dd> 
    <dt>What are your hours?</dt> 
    <dd>We are open 24/7.</dd> 
</dl> 

を作成するには、この簡単なスクリプトを使用して、前に、今私は、角2

で書かれたこのコードのコピーを作成したいですAngular 2で上記のような単純なアコーディオンを作成するにはどうすればよいですか?

私はレンダラー、elementRefなどを学ぶ必要があると思います。 これを作成するために学ぶべき他のトピックを提案できますか?

答えて

2

が、これは非常に単純なアコーディオンで、このソリューションを試してみてください。

アプリ/

import { Component, Input, Output, EventEmitter } from '@angular/core'; 

@Component({ 
    selector: 'tp-accordion', 
    template: ` 
    <h2 class="accordion-head" (click)="onClick($event)">{{ title }}</h2> 
    <div class="accordion-body" [class.active]="active"> 
     <ng-content></ng-content> 
    </div> 
    `, 
    styles: [ 
    ` 
    .accordion-head { 
     cursor: pointer; 
    } 
    .accordion-body { 
     display: none; 
    } 
    .accordion-body.active { 
     display: block; 
     -webkit-animation: fadeIn .3s; 
     animation: fadeIn .3s; 
    } 
    @-webkit-keyframes fadeIn { 
     from { opacity: 0; transform: scale(0); } 
     to { opacity: 1; transform: scale(1); } 
    } 
    @keyframes fadeIn { 
     from { opacity: 0; transform: scale(0); } 
     to { opacity: 1; transform: scale(1); } 
    } 
    ` 
    ], 
}) 
export class Accordion { 

    @Input() title: string; 

    @Input() active: boolean = false; 

    @Output() toggleAccordion: EventEmitter<boolean> = new EventEmitter(); 

    constructor() {} 

    onClick(event) { 
    event.preventDefault(); 
    this.toggleAccordion.emit(this.active); 
    } 

} 

アプリ/アコーディオンgroup.component.ts

import { Component, ContentChildren, QueryList, AfterContentInit, OnDestroy } from '@angular/core'; 

import { Accordion } from './accordion.component'; 

@Component({ 
    selector: 'tp-accordion-group', 
    template: ` 
    <ng-content></ng-content> 
    ` 
}) 
export class AccordionGroup { 

    @ContentChildren(Accordion) accordions: QueryList<Accordion>; 
    private subscriptions = []; 

    private _accordions = []; 

    constructor() {} 

    ngAfterContentInit() { 

    this._accordions = this.accordions; 
    this.removeSubscriptions(); 
    this.addSubscriptions(); 

    this.accordions.changes.subscribe(rex => { 
     this._accordions = rex; 
     this.removeSubscriptions(); 
     this.addSubscriptions(); 
    }); 
    } 

    addSubscriptions() { 
    this._accordions.forEach(a => { 
     let subscription = a.toggleAccordion.subscribe(e => { 
     this.toogleAccordion(a); 
     }); 
     this.subscriptions.push(subscription); 
    }); 
    } 

    removeSubscriptions() { 
    this.subscriptions.forEach(sub => { 
     sub.unsubscribe(); 
    }); 
    } 

    toogleAccordion(accordion) { 
    if (!accordion.active) { 
     this.accordions.forEach(a => a.active = false); 
    } 
    // set active accordion 
    accordion.active = !accordion.active; 
    } 

    ngOnDestroy() { 
    this.removeSubscriptions(); 
    } 

} 
をaccordion.component.ts

app/app.component.ts

​​

アプリ/ posts.service.ts

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/catch'; 

@Injectable() 
export class PostsService { 
    postsUrl: 'https://jsonplaceholder.typicode.com/posts'; 
    constructor(private http: Http) { 

    } 
    getPosts() { 
    return this.http.get(this.postsUrl) 
     .map(res => { 
     let body = res.json(); 
     return body || []; 
     }) 
     .catch(console.log); 
    } 
} 

オンラインデモ:https://plnkr.co/edit/xFBllK?p=preview

ドキュメント:

+0

こんにちは@Tiep、答えてくれてありがとう:ここ

サンプル

は私が上記を正確に何をしたサンプルです。私はそれを使用しようとしています。私はあなたにもう1つの質問をしたいのですが、私のコンテンツがajaxリクエストから来たらどうしますか?私は、AJAXのリクエストがロードされた後に、アコーディオン・グループ・コンポーネントを初期化しなければならないと思います。しかし今、ngAfterContentInitに取り組んでいます。それともサービスを作るべきですか? – Sam

+0

あなたのコンテンツを ' ... content ...の中に入れてください。 –

+0

動的コンテンツを意味するなら、試しました。 * ngForを使用してjson経由でコンテンツを読み込むと、accordionをクリックするとtoogleAccordionメソッドがトリガされません。 – Sam

0

問題

は奪う最大のものは、「GetElementbyClassName」を知っているか、DOMがするので、これは角2内で呼び出されている場合を除き「getElementByIdを」は動作しません。 Angularコンポーネントがロードされる前に常にロードされるので、クラスやIDを取得するオブジェクトは決して存在しません。

ソリューション

角度は、このようなコンポーネントの負荷がngAfterViewInit()

これは、すべてのディレクティブを使用することによって回避することができたときのように、あなたがそれを活用できる「フック」は、特定のイベントが発生したときにコードを実行できるようになりますが、持っていますあなたのアコーデオンを行うには、上記のjavascriptを実行する場合は、ちょうどexport class componentName {}ngAfterViewInit()関数で実行し、それが動作します。

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

@Component({ 
    selector: 'events', 
    templateUrl: "partials/events.html" 
}) 
export class EventsComponent { 
    ngAfterViewInit() { 
     var acc = document.getElementsByClassName("accordion"); 
     var i; 

for (i = 0; i < acc.length; i++) { 
    acc[i].onclick = function(){ 
     this.classList.toggle("active"); 
     this.nextElementSibling.classList.toggle("show"); 
     } 
    } 
} 

} // export class 
+0

onclickはコンパイル中にエラーを返します。 – Sam

関連する問題