前のチュートリアルでは、Discourseのサーバー側とクライアント側の両方を設定してリクエストに応答する方法を紹介しました。
現在、Emberコンポーネントのドキュメントを読むことをお勧めします: Introducing Components - Components - Ember Guides
コンポーネントを作成する前に、共有コンポーネント、ヘルパー、モディファイアを含むUIキットを確認してください。ほとんどの一般的なコントロールはすでにそこに存在します。
古いチュートリアル
このチュートリアルでは、サードパーティの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で行ってください。