前回のチュートリアルでは、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で行ってください。