[解決済み] Angular 2で簡単なアコーディオンを作成するにはどうすればよいですか?
2022-01-30 03:28:40
質問
以前は、この簡単なスクリプトを使って、簡単なアコーディオンを作っていました。
(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>
では、Angular 2で書かれたこのコードのコピーを作りたいと思います。
Angular 2で上記のようなシンプルなアコーディオンを作成するにはどうすればよいですか?
レンダラー、elementRefなどを学ばなければならないのでしょうね。 これを作成するために学ぶべき他のトピックを提案することができますか?
どのように解決するのですか?
これは非常にシンプルなアコーディオンです。
app/accordion.component.ts
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);
}
}
app/accordion-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();
}
}
app/app.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { PostsService } from './posts.service';
@Component({
selector: 'app-root',
template: `
<tp-accordion-group>
<tp-accordion *ngFor="let post of posts" [title]="post.title">
{{ post.body }}
</tp-accordion>
</tp-accordion-group>
`
})
export class AppComponent implements OnInit, OnDestroy {
posts = [];
private subscription: any;
constructor(private postsSvc: PostsService) {}
ngOnInit() {
this.subscription = this.postsSvc.getPosts().subscribe(res => {
if (res.length) {
this.posts = res.slice(0, 10);
}
})
}
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
}
app/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
ドキュメント
関連
-
[解決済み] Angular "未定義のプロパティ 'subscribe' を読み取ることができません".
-
[解決済み] ブレークポイントの解除 - VS Code | Chrome | Angular
-
[解決済み] コンポーネントは2つのモジュールの宣言に含まれる
-
[解決済み] Angular 4 - "BrowserAnimationsModule "または "NoopAnimationsModule "のいずれかをアプリケーションに組み込んでください。
-
[解決済み] Angular:*ngClassを使った条件付きクラス
-
[解決済み] NGIf else "の使い方を教えてください。
-
[解決済み] Angularで@Input()の値が変更されたときに検出する方法は?
-
[解決済み] Angular 2の "select "で新しい選択範囲を取得するにはどうすればよいですか?
-
[解決済み】AngularでjQueryを使用するには?
-
[解決済み】Angularでルート変更を検出する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Angularで実際のエラーメッセージの代わりに「Http failure response for (unknown url): 0 Unknown Error」が表示されるのですが。
-
[解決済み】Angular: オブジェクトをサポートしているdiffが見つからない '[object Object]'
-
[解決済み] チョキダーからのエラー(C:┣ᴗ┣)。Error: EBUSY: resource busy or locked, lstat 'C:\DumpStack.log.tmp.
-
[解決済み] 未定義のプロパティ 'filter' を読み取ることができません。
-
[解決済み] Visual Code で未定義のプロパティ 'thisCompilation' を読み取ることができません。
-
[解決済み] イオン4オブザーバブル
-
[解決済み] Angular 2 ルーターベースなし href = "/stock/stock_detail.html?
-
[解決済み] AngularのmatSortがソートされない
-
[解決済み] このメソッドをリファクタリングして、認知的複雑度を21から許容される15に下げます。リファクタリングして複雑さを軽減する方法
-
[解決済み] Angular 2の「コンポーネント」は既知の要素ではありません。