WinJSでの宣言的なデータバインディング

メトロの翻訳:Stephen Waltherによる宣言的データバインディング



この記事の目的は、WinJSライブラリで宣言型データバインディングがどのように機能するかを説明することです。 特に、data-win-bindおよびdata-win-bindsource属性の使用方法を学習します。 また、計算されたプロパティとコンバータを使用して、データをバインドするときにプロパティ値を自動的にフォーマットする方法も学習します。



WinJSでデータバインディングを使用すると、JavaScriptでMetroスタイルアプリケーションを構築するときにModel-View-ViewModel(MVVM)テンプレートを使用できます。 MVVMテンプレートを使用すると、コードが混乱するのを防ぎます。 MVVMテンプレートは、JavaScriptコードを整理する標準的な方法を提供し、アプリケーションをより簡単にサポートできるようにします。



宣言的バインディングの使用



ページ上の任意のHTML要素でdata-win-bind属性を使用できます。 data-win-bind属性を使用すると、HTML属性をオブジェクトのJavascriptプロパティに関連付けることができます。



たとえば、特定の製品に関するページを作成し、この製品に関する情報をページに表示する必要があります。

この場合、次のHTMLページを作成して製品の詳細を表示できます。



<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Application1</title> <!-- WinJS references --> <link href="//Microsoft.WinJS.0.6/css/ui-dark.css" rel="stylesheet"> <script src="//Microsoft.WinJS.0.6/js/base.js"></script> <script src="//Microsoft.WinJS.0.6/js/ui.js"></script> <!-- Application1 references --> <link href="http://3a0ojxkezud2pogen3j4z0w18nq.wpengine.netdna-cdn.com/css/default.css" rel="stylesheet"> <script src="http://3a0ojxkezud2pogen3j4z0w18nq.wpengine.netdna-cdn.com/js/default.js"></script> </head> <body> <h1>Product Details</h1> <div class="field"> Product Name: <span data-win-bind="innerText:name"></span> </div> <div class="field"> Product Price: <span data-win-bind="innerText:price"></span> </div> <div class="field"> Product Picture: <br /> <img data-win-bind="src:photo;alt:name" /> </div> </body> </html>
      
      





上記のページには、3つのdata-win-bind属性が含まれています(製品プロパティごとに1つの属性)。 data-win-bind属性を使用して、HTML要素のプロパティを設定します。 data-win-bind属性は、セミコロンで区切られたペア<element property>:<model property>のリストを受け入れます。



data-win-bind =” elementPropertyName:datasourcePropertyName; elementPropertyName:datasourcePropertyName; ...”



このページでは、最初の2つのdata-win-bind属性を使用して、SPAN要素のinnerTextプロパティを設定します。 最後のdata-win-bind属性は、IMG要素のsrc属性とalt属性に使用されます。



ちなみに、data-win-bind属性の使用はHTML5で完全に有効です。 HTML5標準では、接頭辞data-を付けて、HTMLドキュメントにカスタム属性を追加できます。 このようにして、HTML5ドキュメントにdata-stephen、data-funky、またはdata-rover-dog-is-hungryのような名前のカスタム属性を追加でき、ドキュメントは有効なままです。



上記のページに表示される製品オブジェクトは、default.jsファイルに作成されます。



 (function () { "use strict"; var app = WinJS.Application; app.onactivated = function (eventObject) { if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) { var product = { name: "Tesla", price: 80000, photo: "/images/TeslaPhoto.png" }; WinJS.Binding.processAll(null, product); } }; app.start(); })();
      
      





このコードでは、名前、価格、および写真のプロパティを使用して製品オブジェクトが作成されます。 WinJS.Binding.processAll()メソッドは、モデルをビューにバインドするために呼び出されます(WinJS.Binding.processAll()およびWinJS.UI.processAll()メソッドを混同しないでください-これらは完全に異なるメソッドです)。



processAll()メソッドの最初のパラメーターは、バインドするルート要素を表します。 つまり、この要素とそのすべての子孫に対してバインディングが発生します。 nullを指定すると、ドキュメントの本体全体(document.body)にバインドされます。



2番目のパラメーターは、データコンテキストを表します。 これは、data-win-bind属性を使用して表示されるプロパティオブジェクトです。 以下のコードでは、製品オブジェクトがデータコンテキストパラメーターとして渡されます。 つまり、データコンテキストはプレゼンテーションモデルです。



複雑なプレゼンテーションモデルの作成



前のセクションでは、data-win-bind属性を使用して、単純なオブジェクト(単一の製品)のプロパティを表示しました。 ただし、オブジェクトの階層を表すプレゼンテーションモデルなど、より複雑なプレゼンテーションモデルとのバインディングを使用することもできます。



たとえば、次のdefault.jsファイルのビューモデルは、2つの顧客オブジェクトと製品オブジェクトを表します。 次に、顧客オブジェクトには住所オブジェクトが含まれます。



 (function () { "use strict"; var app = WinJS.Application; app.onactivated = function (eventObject) { if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) { var viewModel = { customer: { firstName: "Fred", lastName: "Flintstone", address: { street: "1 Rocky Way", city: "Bedrock", country: "USA" } }, product: { name: "Bowling Ball", price: 34.55 } }; WinJS.Binding.processAll(null, viewModel); } }; app.start(); })();
      
      





次のページには、ユーザー情報(住所を含む)と製品が表示されます。 ポイントを使用して、customer.address.streetなどのモデルの子オブジェクトにアクセスすることに注意してください。



 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Application1</title> <!-- WinJS references --> <link href="//Microsoft.WinJS.0.6/css/ui-dark.css" rel="stylesheet"> <script src="//Microsoft.WinJS.0.6/js/base.js"></script> <script src="//Microsoft.WinJS.0.6/js/ui.js"></script> <!-- Application1 references --> <link href="http://3a0ojxkezud2pogen3j4z0w18nq.wpengine.netdna-cdn.com/css/default.css" rel="stylesheet"> <script src="http://3a0ojxkezud2pogen3j4z0w18nq.wpengine.netdna-cdn.com/js/default.js"></script> </head> <body> <h1>Customer Details</h1> <div class="field"> First Name: <span data-win-bind="innerText:customer.firstName"></span> </div> <div class="field"> Last Name: <span data-win-bind="innerText:customer.lastName"></span> </div> <div class="field"> Address: <address> <span data-win-bind="innerText:customer.address.street"></span> <br /> <span data-win-bind="innerText:customer.address.city"></span> <br /> <span data-win-bind="innerText:customer.address.country"></span> </address> </div> <h1>Product</h1> <div class="field"> Name: <span data-win-bind="innerText:product.name"></span> </div> <div class="field"> Price: <span data-win-bind="innerText:product.price"></span> </div> </body> </html>
      
      





ビューモデルは必要に応じて複雑にすることができ、宣言型バインディングを使用してモデルをビューに関連付けることができます。



計算プロパティの作成



プロパティを表示するときに、プロパティの変更が必要になる場合があります。



たとえば、表示される製品の価格をフォーマットする必要があります。 このフォーム「80,000」で製品の価格を表示したくありません。 代わりに、最初にフォーマット設定して価格を表示する必要があります:「$ 80,000」。



複数のプロパティを組み合わせて表示する必要がある場合もあります。 たとえば、フルネームは、姓、名、およびパトロニーミックのフィールドで構成されます。



このような場合、データバインディングでメソッドを呼び出すと便利です。 たとえば、姓と名を連結するfullName()メソッドを作成できます。 残念ながら、WinJSは次の構文をサポートしていません。



 <span data-win-bind=”innerText:fullName()”></span>
      
      





代わりに、このような場合、ビューモデルにゲッタープロパティを作成する必要があります。 たとえば、default.jsファイルの顧客オブジェクトには、firstNameプロパティとlastNameプロパティを連結するfullNameプロパティが含まれています。



 (function () { "use strict"; var app = WinJS.Application; app.onactivated = function (eventObject) { if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) { var customer = { firstName: "Fred", lastName: "Flintstone", get fullName() { return this.firstName + " " + this.lastName; } }; WinJS.Binding.processAll(null, customer); } }; app.start(); })();
      
      





したがって、顧客オブジェクトにはプロパティfirstName、lastName、fullNameが含まれます。 fullNameプロパティはゲッター関数で宣言されていることに注意してください。 fullNameプロパティを使用すると、firstNameプロパティとlastNameプロパティの値が連結され、単一の文字列として返されます。



次のHTMLページは、H1要素のfullNameプロパティを表示します。 他のプロパティと同様に、data-win-bind属性でfullNameプロパティを使用できます。



 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Application1</title> <!-- WinJS references --> <link href="//Microsoft.WinJS.0.6/css/ui-dark.css" rel="stylesheet"> <script src="//Microsoft.WinJS.0.6/js/base.js"></script> <script src="//Microsoft.WinJS.0.6/js/ui.js"></script> <!-- Application1 references --> <link href="http://3a0ojxkezud2pogen3j4z0w18nq.wpengine.netdna-cdn.com/css/default.css" rel="stylesheet"> <script src="http://3a0ojxkezud2pogen3j4z0w18nq.wpengine.netdna-cdn.com/js/default.js"></script> </head> <body> <h1 data-win-bind="innerText:fullName"></h1> <div class="field"> First Name: <span data-win-bind="innerText:firstName"></span> </div> <div class="field"> Last Name: <span data-win-bind="innerText:lastName"></span> </div> </body> </html>
      
      





コンバーターの作成



前のセクションでは、ゲッタープロパティを作成してプロパティ値を変換する方法を学びました。 このアプローチは、フォーマットロジックが特定のプレゼンテーションモデルに限定されている場合に有効です。



異なるモデルに同じフォーマットアクションを適用する必要がある場合は、コンバーター関数を作成するのが理にかなっています。 コンバーターは、data-win-bind属性を使用するときにいつでも使用できる関数です。



たとえば、日付を表示する一般的な方法を作成する必要があるとします。 そして、あなたは常に12/25/1988の短い形式で日付を表示したいです。 converters.jsという次のファイルには、shortDate()コンバーターが含まれています。



 (function (WinJS) { var shortDate = WinJS.Binding.converter(function (date) { return date.getMonth() + 1 + "/" + date.getDate() + "/" + date.getFullYear(); }); // Export shortDate WinJS.Namespace.define("MyApp.Converters", { shortDate: shortDate }); })(WinJS);
      
      





上記のファイルでは、モジュールテンプレートが使用されています。これは、WinJSライブラリのあらゆる場所で使用されています。 モジュールテンプレートの詳細については、名前空間とモジュールに関するメモをお読みください。

http://stephenwalther.com/blog/archive/2012/02/22/windows-web-applications-namespaces-and-modules.aspx



このファイルには、shortDate()関数の定義が含まれています。 この関数はJavaScriptの組み込み日付オブジェクトを短い日付文字列12/1/1988に変換します。



コンバーターは、WinJS.Binding.converter()コンバーター作成メソッドを使用して作成されます。 このメソッドは通常の関数を取り、コンバーターを返します。



最後に、shortDate()コンバーターがMyApp.Converters名前空間に追加されます。 MyApp.Converters.shortDate()を呼び出すことにより、shortDate()関数を呼び出すことができます。



default.jsファイルには、バインドするユーザーオブジェクトが含まれています。 ユーザーオブジェクトには、プロパティfirstName、lastName、およびbirthdayが含まれます。 ユーザーオブジェクトの誕生日プロパティを表示するときに、新しい新しいshortDate()コンバーターを使用します。



 (function () { "use strict"; var app = WinJS.Application; app.onactivated = function (eventObject) { if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) { var customer = { firstName: "Fred", lastName: "Flintstone", birthday: new Date("12/1/1988") }; WinJS.Binding.processAll(null, customer); } }; app.start(); })();
      
      





その結果、shortDateからHTMLドキュメントへのコンバーターを使用します。 次のHTMLドキュメントには、ユーザーオブジェクトのすべてのプロパティが表示されます。



 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Application1</title> <!-- WinJS references --> <link href="//Microsoft.WinJS.0.6/css/ui-dark.css" rel="stylesheet"> <script src="//Microsoft.WinJS.0.6/js/base.js"></script> <script src="//Microsoft.WinJS.0.6/js/ui.js"></script> <!-- Application1 references --> <link href="http://3a0ojxkezud2pogen3j4z0w18nq.wpengine.netdna-cdn.com/css/default.css" rel="stylesheet"> <script src="http://3a0ojxkezud2pogen3j4z0w18nq.wpengine.netdna-cdn.com/js/default.js"></script> <script type="text/javascript" src="js/converters.js"></script> </head> <body> <h1>Customer Details</h1> <div class="field"> First Name: <span data-win-bind="innerText:firstName"></span> </div> <div class="field"> Last Name: <span data-win-bind="innerText:lastName"></span> </div> <div class="field"> Birthday: <span data-win-bind="innerText:birthday MyApp.Converters.shortDate"></span> </div> </body> </html>
      
      





誕生日プロパティを表示するためにdata-win-bind属性がどのように使用されるかに注意してください。



 <span data-win-bind="innerText:birthday MyApp.Converters.shortDate"></span>
      
      





shortDateコンバーターは、SPANエレメントのinnerTextプロパティにバインドされている誕生日プロパティに適用されます。



data-win-bindsourceの使用



通常は、data-win-bind属性で使用するビューモデル(データコンテキスト)を定義し、この方法でWinJS.Binding.processAll()メソッドにパラメーターとして渡します。



 WinJS.Binding.processAll(null, viewModel);
      
      





または、data-win-datasource属性を使用して、マークアップでモデルを宣言的に指定できます。 たとえば、default.jsスクリプトでは、ビューモデルへのアクセスを提供します。 完全なパス-MyWinWebApp.viewModelを指定してモデルを取得できます。



 (function () { "use strict"; var app = WinJS.Application; app.onactivated = function (eventObject) { if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) { // Create view model var viewModel = { customer: { firstName: "Fred", lastName: "Flintstone" }, product: { name: "Bowling Ball", price: 12.99 } }; // Export view model to be seen by universe WinJS.Namespace.define("MyWinWebApp", { viewModel: viewModel }); // Process data-win-bind attributes WinJS.Binding.processAll(); } }; app.start(); })();
      
      





上記のコードでは、ユーザーフィールドと製品フィールドを持つビューモデルはMyWinWebApp.viewModelとして表されています。



次のHTMLページは、data-win-bindsource属性を使用してこのビューモデルにバインドする方法を示しています。



 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Application1</title> <!-- WinJS references --> <link href="//Microsoft.WinJS.0.6/css/ui-dark.css" rel="stylesheet"> <script src="//Microsoft.WinJS.0.6/js/base.js"></script> <script src="//Microsoft.WinJS.0.6/js/ui.js"></script> <!-- Application1 references --> <link href="http://3a0ojxkezud2pogen3j4z0w18nq.wpengine.netdna-cdn.com/css/default.css" rel="stylesheet"> <script src="http://3a0ojxkezud2pogen3j4z0w18nq.wpengine.netdna-cdn.com/js/default.js"></script> </head> <body> <h1>Customer Details</h1> <div data-win-bindsource="MyWinWebApp.viewModel.customer"> <div class="field"> First Name: <span data-win-bind="innerText:firstName"></span> </div> <div class="field"> Last Name: <span data-win-bind="innerText:lastName"></span> </div> </div> <h1>Product</h1> <div data-win-bindsource="MyWinWebApp.viewModel.product"> <div class="field"> Name: <span data-win-bind="innerText:name"></span> </div> <div class="field"> Price: <span data-win-bind="innerText:price"></span> </div> </div> </body> </html>
      
      





data-win-bindsource属性は、上記のページで2回使用されます。ユーザーの詳細を含む要素と、製品の詳細を含む要素で使用されます。



data-win-bindsource属性で指定されたモデルコンテキストは、すべての子要素に渡されます。 子要素のdata-win-bind属性は、data-win-bindsource属性で指定されたコンテキストにバインドされます。



まとめ



この記事は、WinJSライブラリのデータバインディングについてでした。 data-win-bind属性を使用して、HTML要素の属性をビューモデルにバインドする方法を学習しました。 また、いくつかの追加のデータバインディング機能についても調べました。 ビューモデルでゲッタープロパティを使用して、計算されたプロパティを使用して計算しました。 また、プロパティをバインドするときにビューモデルの値をフォーマットするコンバーターを作成する方法も検討しました。 最後に、data-win-bindsource属性を使用して、ビューモデルを宣言的に指定する方法を学びました。



All Articles