前のチュートリアルでは、Discourse のサーバー側とクライアント側の両方を設定してリクエストに応答させる方法を紹介しました。
現在、Ember コンポーネントのドキュメントを読むことをお勧めします:Introducing Components - Components - Ember Guides
旧チュートリアル
このチュートリアルでは、サードパーティ製の JavaScript をラップする方法として、新しい Ember コンポーネントを作成します。これは、以前に作成した YouTube の動画と似ていますが、今回は Discourse に特化しており、プロジェクト内のファイルの配置方法についても説明します。
なぜコンポーネントなのか?
Handlebars は非常にシンプルで魅力的な言語です。動的な要素を含む通常の HTML のようなものです。これは学習が簡単で生産性が高いですが、コードの再利用という点ではあまり優れていません。Discourse のような大規模なアプリケーションを開発している場合、同じものを何度も再利用したいことに気づくでしょう。
コンポーネントは、Ember がこの問題に対する解決策です。スナックをより見やすく表示するコンポーネントを作成してみましょう。
新しいコンポーネントの作成
コンポーネントの名前にはダッシュを含める必要があります。今回は fancy-snack という名前にします。テンプレートを作成しましょう:
app/assets/javascripts/admin/templates/components/fancy-snack.hbs
<div class="fancy-snack-title">
<h1>{{snack.name}}</h1>
</div>
<div class="fancy-snack-description">
<p>{{snack.description}}</p>
</div>
次に、既存の admin/snack テンプレートを以下に置き換えて、コンポーネントを使用します:
app/assets/javascripts/admin/templates/snack.hbs
{{fancy-snack snack=model}}
これで、必要なモデルを渡すだけで、fancy-snack コンポーネントを他のどのテンプレートでも再利用できるようになります。
カスタム JavaScript コードの追加
再利用性に加えて、Ember のコンポーネントは、カスタム JavaScript、jQuery、およびその他の外部コードを安全に追加するのに役立ちます。コンポーネントがページに挿入されるタイミングと削除されるタイミングを制御できます。これを行うには、いくつかのコードと共に Ember.Component を定義します:
app/assets/javascripts/admin/components/fancy-snack.js
export default Ember.Component.extend({
didInsertElement() {
this._super();
this.$().animate({ backgroundColor: "yellow" }, 2000);
},
willDestroyElement() {
this._super();
this.$().stop();
},
});
上記のコードを追加してページを更新すると、スナックがゆっくりと黄色い背景にフェードするアニメーションが表示されます。
ここで何が起こっているかを説明しましょう:
-
コンポーネントがページにレンダリングされると、
didInsertElementが呼び出されます。 -
didInsertElement(およびwillDestroyElement)の最初の行はthis._super()です。これは、Ember.Component をサブクラス化しているため必要です。 -
アニメーションは、jQuery の animate 関数を使用して行われます。
-
最後に、アニメーションはコンポーネントがページから削除される際に呼び出される
willDestroyElementフックでキャンセルされます。
なぜ willDestroyElement にこだわるのか疑問に思うかもしれません。その理由は、Discourse のような長寿命の JavaScript アプリケーションでは、メモリリークを防いだり、不要な処理を残したりしないために、自身の後始末をすることが重要だからです。この場合、アニメーションを停止することで、コンポーネントがページに表示されなくなったため、jQuery のタイマーがこれ以上発火する必要がないことを伝えます。
次のステップ
このシリーズの最終チュートリアルでは、自動テストについて取り上げています。
このドキュメントはバージョン管理されています。変更を GitHub で提案してください。