Backbone テンプレート
作成者: Mads Kristensen
Backbone SPA テンプレートは Kazi Manzur Rashid が作成しました
Backbone.js SPA テンプレートは、Backbone.js を使って対話型のクライアント側 Web アプリをすばやく構築できるように設計されています。
このテンプレートは、ASP.NET MVC で Backbone.js アプリケーションを開発するための初期スケルトンを備えています。 既定で使用できる基本的なユーザー ログイン機能 (ユーザーのサインアップ、サインイン、パスワード リセット、基本的なメール テンプレートを使ったユーザーの確認など) が用意されています。
要件:
Backbone テンプレート プロジェクトを作成する
上の [ダウンロード] ボタンをクリックして、テンプレートをダウンロードしてインストールします。 このテンプレートは、Visual Studio 拡張機能 (VSIX) ファイルとしてパッケージ化されています。 Visual Studio の再起動が必要になることがあります。
[テンプレート] ウィンドウで、[インストールされているテンプレート] を選び、[Visual C#] ノードを展開します。 [Visual C#] で [Web] を選びます。 プロジェクト テンプレートの一覧で、[ASP.NET MVC 4 Web アプリケーション] を選びます。 プロジェクト名を指定して、 [OK] をクリックします。
[新しいプロジェクト] ウィザードで、Backbone.js SPA プロジェクトを選びます。
Ctrl + F5 キーを押してデバッグなしでアプリケーションをビルドして実行するか、F5 キーを押してデバッグありで実行します。
[マイ アカウント] をクリックすると、ログイン ページが表示されます。
チュートリアル: クライアント コード
まず、クライアント側から始めましょう。 クライアント アプリケーション スクリプトは、~/Scripts/application フォルダーにあります。 アプリケーションは TypeScript (.ts ファイル) で書かれており、JavaScript (.js ファイル) にコンパイルされます。
Application
Application
は application.ts で定義されています。 このオブジェクトを使ってアプリケーションを初期化します。また、ルート名前空間として機能します。 ユーザーがサインインしているかどうかなど、アプリケーション全体で共有される構成情報と状態情報を保持します。
application.start
メソッドを使って、モーダル ビューを作成し、ユーザー サインインなどのアプリケーション レベル イベントのイベント ハンドラーをアタッチします。 次に、既定のルーターを作成し、クライアント側 URL が指定されているかどうかを確認します。 されていない場合は、既定の URL (#!/) にリダイレクトされます。
イベント
疎結合コンポーネントを開発する場合、イベントは常に重要です。 多くの場合、アプリケーションはユーザーのアクションに応じて複数の操作を実行します。 Backbone には、モデル、コレクション、ビューなどのコンポーネントを含む組み込みイベントが用意されています。 このテンプレートでは、これらのコンポーネント間に相互依存関係を作成する代わりに、"pub/sub" モデルを使います。events.ts に定義されている events
オブジェクトは、アプリケーション イベントの発行とサブスクライブのためのイベント ハブとして機能します。 events
オブジェクトはシングルトンです。 次のコードは、イベントをサブスクライブしてからイベントをトリガーする方法を示しています。
events.on('myEvent', (e: MyEventArg) => {
// Do your work
});
// Later in the code
events.trigger('myEvent', { arg: 'myValue' });
ルーター
Backbone.js のルーターには、クライアント側ページをルーティングし、それらをアクションやイベントに接続するためのメソッドが用意されています。 このテンプレートでは、router.ts に 1 つのルーターを定義します。 ルーターによって操作可能ビューが作成され、ビューの切り替え時にその状態が維持されます (操作可能ビューについては、次のセクションで説明します)。初期状態のプロジェクトには Home と About という 2 つのダミー ビューがあります。 また、ルートが不明な場合に表示される NotFound ビューもあります。
ビュー
ビューは ~/Scripts/application/views で定義されています。 操作可能ビューとモーダル ダイアログ ビューという 2 種類のビューがあります。 操作可能ビューはルーターによって呼び出されます。 ある操作可能ビューが表示されると、他の操作可能ビューはすべて非アクティブになります。 操作可能ビューを作成するには、Activable
オブジェクトを使ってビューを拡張します。
export class MyView extends Backbone.View {
// Other implementation details
}
// Extending with Activable
_.extend(MyView.prototype, Activable);
Activable
を使って拡張すると、activate
と deactivate
という 2 つの新しいメソッドがビューに追加されます。 ルーターはこれらのメソッドを呼び出して、ビューのアクティブ化と非アクティブ化を行います。
モーダル ビューは、Twitter Bootstrap モーダル ダイアログとして実装されます。 Membership
と Profile
のビューはモーダル ビューです。 モデル ビューは、任意のアプリケーション イベントによって呼び出すことができます。 たとえば、Navigation
ビューで [マイ アカウント] リンクをクリックすると、ユーザーがログインしているかどうかに応じて、Membership
ビューまたは Profile
ビューのいずれかが表示されます。 Navigation
は、data-command
属性を持つすべての子要素にクリック イベント ハンドラーをアタッチします。 HTML マークアップを次に示します。
<li>
<a href="#" data-command="myAccount">
<i class="icon-user"></i> My Account
</a>
</li>
イベントをフックする Navigation.ts のコードを次に示します。
export class Navigation extends Backbone.View {
// Other implementation details
handleCommand(e: JQueryEventObject) {
var command = $(e.currentTarget).attr('data-command');
if (command) {
events.trigger(command);
}
}
}
Navigation.prototype.events = () => {
return {
'click [data-command]': 'handleCommand'
};
};
Models
モデルは ~/Scripts/application/models で定義されます。 すべてのモデルには、既定の属性、検証規則、サーバー側エンド ポイントという 3 つの基本的な要素があります。 一般的な例を次に示します。
export class Session extends Backbone.Model {
urlRoot() {
return serverUrlPrefix + '/sessions'
}
defaults(): ISessionAttributes {
return {
email: null,
password: null,
rememberMe: false
}
}
validate(attributes: ISessionAttributes): IValidationResult {
var errors = {};
if (!attributes.email) {
Validation.addError(errors, 'email', 'Email is required.');
}
if (!attributes.password) {
Validation.addError(errors, 'password', 'Password is required.');
}
if (!_.isEmpty(errors)) {
return { errors: errors };
}
}
}
プラグイン
~/Scripts/application/lib フォルダーには、いくつかの便利な jQuery プラグインがあります。form.ts ファイルには、フォーム データを操作するためのプラグインが定義されています。 多くの場合、フォーム データをシリアル化または逆シリアル化し、モデル検証エラーを表示する必要があります。 form.ts プラグインには、serializeFields
、deserializeFields
、showFieldErrors
などのメソッドがあります。 次の例は、フォームをモデルにシリアル化する方法を示しています。
// Here $el is the form element
// Hide existing errors if there is any
this.$el.hideSummaryError().hideFieldErrors();
// Subscribe invalid event which
// is fired when validation fails
model.on('invalid', () =>
this.$el.showFieldErrors{(
errors: model.validationError.errors;
)}
);
model.save(this.$el.serializeFields(), {
success: () => { }, // lets do something good
error: (m, jqxhr: JQueryXHR) => {
if (jqxhr.status === 400) { // bad request
// Handle server side field errors
var response = <any>$.parseJSON(jqxhr.responseText);
if (response && _.has(response, 'ModelState')) {
return this.$el.showFieldErrors({
errors: response.ModelState
});
}
}
// All other server errors
this.$el.showSummaryError({
message: 'An unexpected error has occurred while performing ' +
'operation.'
});
}
});
flashbar.ts プラグインは、さまざまなフィードバック メッセージをユーザーに提供します。 メソッドは $.showSuccessbar
、$.showErrorbar
、$.showInfobar
です。 バックグラウンドでは、きれいにアニメーション化されたメッセージを表示するために Twitter Bootstrap アラートが使われます。
verify.ts プラグインはブラウザーの確認ダイアログを置き換えるものですが、API は多少異なります。
$.confirm({
prompt: 'Are you sure you want to do it?',
ok: => { //Do something useful },
cancel: => { // Do something else }
)};
チュートリアル: サーバー コード
次にサーバー側を見てみましょう。
コントローラー
単一ページ アプリケーションのユーザー インターフェイスでサーバーが果たす役割は小さなものです。 通常、サーバーは最初のページをレンダリングしてから、JSON データを送受信します。
テンプレートには 2 つの MVC コントローラーがあります。最初のページをレンダリングする HomeController
と、新しいユーザー アカウントの確認とパスワードのリセットに使われる SupportsController
です。 テンプレート内の他のすべてのコントローラーは、JSON データを送受信する ASP.NET Web API コントローラーです。 既定では、コントローラーは新しい WebSecurity
クラスを使ってユーザー関連のタスクを実行します。 ただし、これらのタスクのデリゲートを渡すことができる省略可能なコンストラクターもあります。 これによりテストが容易になり、IoC コンテナーを使って WebSecurity
を他のものに置き換えることができます。 例を次に示します。
public class SessionsController : ApiController
{
private readonly Func<string, string, bool, bool> signIn;
private readonly Action signOut;
public SessionsController() : this(WebSecurity.Login, WebSecurity.Logout)
{
}
public SessionsController(
Func<string, string, bool, bool> signIn,
Action signOut)
{
this.signIn = signIn;
this.signOut = signOut;
}
// Rest of the code
}
ビュー
ビューはモジュール式に設計されています。ページの各セクションには独自の専用ビューがあります。 単一ページ アプリケーションの場合、対応するコントローラーのないビューを含めるのが一般的です。 @Html.Partial('myView')
を呼び出すことでビューを含めることができますが、これは面倒です。 これを簡単にするために、このテンプレートでは、指定されたフォルダー内のすべてのビューをレンダリングするヘルパー メソッド IncludeClientViews
を定義しています。
@Html.IncludeClientViews('yourViewFolder')
フォルダー名が指定されていない場合、既定のフォルダー名は "ClientViews" です。 クライアント ビューでも部分ビューを使う場合は、部分ビューの名前にアンダースコア文字を付けます (たとえば、_SignUp
)。 IncludeClientViews
メソッドを使って、名前がアンダースコアで始まるビューを除外します。 クライアント ビューに部分ビューを含めるには、Html.Partial('_SignUp')
ではなく Html.ClientView('SignUp')
を呼び出します。
メールの送信
メールを送信するために、このテンプレートでは Postal を使っています。 ただし、Postal は IMailer
インターフェイスを使ってコードの残りの部分から抽象化されているため、別の実装に簡単に置き換えることができます。 メール テンプレートは、Views/Emails フォルダーにあります。 送信者のメール アドレスは、web.config ファイルの appSettings セクションの sender.email
キーで指定します。 また、web.config で debug="true"
を指定すると、アプリケーションでユーザー メールの確認が不要になるため、開発をスピードアップできます。
GitHub
Backbone.js SPA テンプレートは、GitHub にもあります。