EmberJS テンプレート

作成者: Xinyang Qiu

EmberJS MVC テンプレートは、Nathan Totten、Thiago Santos、Xinyang Qiu によって記述されています。

EmberJS MVC テンプレートをダウンロードする

EmberJS SPA テンプレートは、EmberJS を使用して対話型のクライアント側 Web アプリをすばやく構築できるように設計されています。

"シングルページ アプリケーション" (SPA) は、新しいページを読み込むのではなく、単一の HTML ページを読み込み、ページを動的に更新する Web アプリケーションを指す一般的な用語です。 最初のページ読み込みの後、SPA は AJAX 要求を介してサーバーと対話します。

Diagram that shows two boxes labeled Client and Server. An arrow labeled AJAX goes from Client to Server. An arrow labeled H T M L and an arrow labeled J SON go from Server to Client.

AJAX は新しい機能ではありませんが、現在、大規模で高度な SPA アプリケーションの構築と保守を容易にする JavaScript フレームワークがあります。 また、HTML 5 と CSS3 を使用すると、豊富な UI を簡単に作成できます。

EmberJS SPA テンプレートは、Ember JavaScript ライブラリを使用して、AJAX 要求からのページ更新を処理します。 Ember.js は、データ バインディングを使用して、ページを最新のデータと同期します。 これにより、JSON データを処理し、DOM を更新するコードを記述する必要はありません。 代わりに、データの表示方法を Ember.js に指示する宣言属性を HTML に配置します。

サーバー側では、EmberJS テンプレートは KnockoutJS SPA テンプレートとほぼ同じ動作を行います。 ASP.NET MVC を使用して HTML ドキュメントを提供し、ASP.NET Web API を使用してクライアントからの AJAX 要求を処理します。 テンプレートのこれらの側面の詳細については、KnockoutJS テンプレートのドキュメントを参照してください。 このトピックでは、Knockout テンプレートと EmberJS テンプレートの違いに焦点を当てています。

EmberJS SPA テンプレート プロジェクトを作成する

上の [ダウンロード] ボタンをクリックして、テンプレートをダウンロードしてインストールします。 Visual Studio の再起動が必要になることがあります。

[テンプレート] ウィンドウで、[インストールされているテンプレート] を選び、[Visual C#] ノードを展開します。 [Visual C#][Web] を選びます。 プロジェクト テンプレートの一覧で、[ASP.NET MVC 4 Web アプリケーション] を選びます。 プロジェクト名を指定して、 [OK] をクリックします。

Screenshot that shows the New Project dialog box. The A S P dot NET M V C 4 Web Application template is selected.

[新しいプロジェクト] ウィザードで、[Ember.js SPA プロジェクト] を選びます。

Screenshot that shows the New A S P dot NET M V C 4 Project dialog box. The Ember dot j s S P A Project template is selected.

EmberJS SPA テンプレートの概要

EmberJS テンプレートでは、jQuery、Ember.js、Handlebars.js の組み合わせを使用して、スムーズな対話型の UI を作成します。

Ember.js は、クライアント側 MVC パターンを使用する JavaScript ライブラリです。

  • テンプレートは、Handlebars テンプレート言語で記述され、アプリケーションのユーザー インターフェイスについて説明します。 リリース モードでは、Handlebars コンパイラを使用し、Handlebars テンプレートをバンドルしてコンパイルします。
  • モデルには、サーバーから取得したアプリケーション データ (ToDo リストと ToDo 項目) が保存されます。
  • コントローラーには、アプリケーションの状態が保存されます。 多くの場合、コントローラーは、対応するテンプレートにモデル データを表示します。
  • ビューは、アプリケーションからプリミティブ イベントを変換し、コントローラーに渡します。
  • ルーターは、アプリケーションの状態を管理し、URL とテンプレートの同期を維持します。

さらに、Ember Data ライブラリを使用して、JSON オブジェクト (RESTful API を介してサーバーから取得) とクライアント モデルを同期できます。

EmberJS SPA テンプレートは、スクリプトを次の 8 つのレイヤーに整理します。

  • webapi_adapter.js、webapi_serializer.js: Ember Data ライブラリを拡張して ASP.NET Web API と連携します。
  • Scripts/helpers.js: 新しい Ember Handlebars ヘルパーを定義します。
  • Scripts/app.js: アプリを作成し、アダプターとシリアライザーを構成します。
  • Scripts/app/models/*.js: モデルを定義します。
  • Scripts/app/views/*.js: ビューを定義します。
  • Scripts/app/controllers/*.js: コントローラーを定義します。
  • Scripts/app/routes、Scripts/app/router.js: ルートを定義します。
  • Templates/*.hbs: Handlebars テンプレートを定義します。

これらのスクリプトのいくつかを詳しく見てみましょう。

モデル

モデルは Scripts/app/models フォルダーで定義されています。 todoItem.js と todoList.js の 2 つのモデル ファイルがあります。

todo.model.js は、To Do リストのクライアント側 (ブラウザー) モデルを定義します。 todoItem と todoList の 2 つのモデル クラスがあります。 Ember では、モデルは DS.Model のサブクラスです。 モデルには、属性を持つプロパティを含めることができます。

todoItemId: attr('number'), 
title: attr('string')

モデルでは、他のモデルとのリレーションシップを定義できます。

todoList: DS.belongsTo('App.TodoList'),

モデルには、他のプロパティにバインドする計算済みプロパティを含めることができます。

hasError: function () {
    var currentError = this.get("error");
    return !(currentError === '' || currentError === null);
}.property('error'),

モデルには、観察対象のプロパティが変更されると呼び出されるオブザーバー関数を含めることができます。

saveCheckbox: function () {
    if(this.get("isDirty")){
        if (this.get("todoItemId")) {
            App.store.commit();
        }
    }
}.observes('isDone'),

ビュー

ビューは Scripts/app/views フォルダーで定義されています。 ビューは、アプリケーション UI からのイベントを変換します。 イベント ハンドラーは、コントローラー関数にコールバックするか、単にデータ コンテキストを直接呼び出すことができます。

たとえば、次のコードは views/TodoItemEditView.js から抜粋したものです。 入力テキスト フィールドのイベント処理を定義します。

App.TodoItemEditView = Em.TextField.extend({
    lastValue: '',
    focusIn: function (evt) {
        this.lastValue = this.get('parentView').templateData.view.content.get("title");
    },
    focusOut: function (evt) {
        this.changeContent();
    },

    insertNewline: function (evt) {
        $(evt.target).blur();
    },

    changeContent: function () {
        var todoItem = this.get('parentView').templateData.view.content;
        var newValue = todoItem.get("title");
        if (this.lastValue != newValue) {
            App.store.commit();
            this.lastValue = newValue;
        }
    }
});

コントローラー

コントローラーは Scripts/app/controllers フォルダーで定義されています。 1 つのモデルを表すには、Ember.ObjectController を拡張します。

App.TodoItemController = Ember.ObjectController.extend({
});

コントローラーは、Ember.ArrayController を拡張することで、モデルのコレクションを表すこともできます。 たとえば、TodoListController は、todoList オブジェクトの配列を表します。 コントローラーは、todoList ID で降順に並べ替えます。

App.TodoListController = Ember.ArrayController.extend({
    error: "",
    sortProperties: ['todoListId'],
    sortAscending: true,

    // ...

コントローラーは addTodoList という名前の関数を定義し、これにより新しい todoList が作成されて配列に追加されます。 この関数の呼び出し方法を確認するには、Templates フォルダーにある todoListTemplate.html という名前のテンプレート ファイルを開きます。 次のテンプレート コードは、ボタンを addTodoList 関数にバインドします。

<input type="button" {{action "addTodoList"}} class="isActive" value="Add Todo list"></input>

コントローラーには、エラー メッセージを保持する error プロパティも含まれています。 エラー メッセージを表示するテンプレート コードを次に示します (todoListTemplate.html にも含まれています)。

<p class="error">{{error}}</p>

Routes

Router.js は、ルートと表示する既定のテンプレートを定義し、アプリケーションの状態を設定し、URL をルートに一致させます。

App.Router.map(function () {
    this.route("index", { path: "/" });
    this.route("about");
    this.route("todoList", { path: "/todo" });
});

TodoListRoute.js は、setupController 関数をオーバーライドして、TodoListRoute のデータを読み込みます。

App.TodoListRoute = Ember.Route.extend({
    setupController: function (controller, model) {
        controller.set('content', App.TodoList.find());
    }
});

Ember は名前付け規則を使用して、URL、ルート名、コントローラー、テンプレートを一致させます。 詳細については、EmberJS ドキュメントの http://emberjs.com/guides/routing/defining-your-routes/ を参照してください。

テンプレート

Templates フォルダーには、次の 4 つのテンプレートが含まれています。

  • application.hbs: アプリケーションの起動時にレンダリングされる既定のテンプレート。
  • about.hbs: "/about" ルートのテンプレート。
  • index.hbs: ルート ("/") ルートのテンプレート。
  • todoList.hbs: "/todo" ルートのテンプレート。
  • _navbar.hbs: このテンプレートはナビゲーション メニューを定義します。

アプリケーション テンプレートは、マスター ページの役割を果たします。 ヘッダー、フッターと、ルートに応じて他のテンプレートを挿入するための "{{outlet}}" が含まれています。 Ember のアプリケーション テンプレートの詳細については、http://guides.emberjs.com/v1.10.0/templates/the-application-template// を参照してください。

"/todoList" テンプレートには、2 つのループ式が含まれています。 外側のループは {{#each controller}} で、内側のループは {{#each todos}} です。 次のコードは、組み込みの Ember.Checkbox ビュー、カスタマイズされた App.TodoItemEditViewdeleteTodo アクションを含むリンクを示しています。

{{view Ember.Checkbox checkedBinding="isDone"}}

{{view App.TodoItemEditView valueBinding="title" class="required" disabledBinding="isDone"}}

<a href="#" {{action "deleteTodo" on="click" target="view"}}>X</a>

Controllers/HtmlHelperExtensions.cs で定義されている HtmlHelperExtensions クラスは、Web.config ファイルで debugtrue に設定されている場合に、テンプレート ファイルをキャッシュして挿入するヘルパー関数を定義します。 この関数は、Views/Home/App.cshtml で定義されている ASP.NET MVC ビュー ファイルから呼び出されます。

@if (HttpContext.Current.IsDebuggingEnabled)
{
    @Html.RenderEmber()
}
else
{
    @Scripts.Render("~/bundles/templates")
}

この関数を引数を付けずに呼び出すと、Templates フォルダー内のすべてのテンプレート ファイルがレンダリングされます。 サブフォルダーまたは特定のテンプレート ファイルを指定することもできます。

Web.config で debugfalse の場合、アプリケーションにはバンドル項目 "~/bundles/templates" が含まれます。 このバンドル項目は、Handlebars コンパイラ ライブラリを使用して、BundleConfig.cs に追加されます。

if (!HttpContext.Current.IsDebuggingEnabled)
{
    bundles.Add(new Bundle("~/bundles/templates", 
        new EmberHandlebarsBundleTransform()).Include(
            "~/scripts/app/templates/*.hbs"
        ));
}