テンプレートを使ってデータをバインドする方法 (HTML)
データの複数のインスタンスを書式設定して表示する場合は、JavaScript 用 Windows ライブラリのテンプレートを使うと便利です。これらのテンプレートを ListView オブジェクトや FlipView オブジェクトと共に使って、オブジェクトを表示する方法を指定できます。また、テンプレートを使うことで、定義済みのビューを使わずにデータ オブジェクトの複数のインスタンスをバインドすることもできます。 ListView とテンプレートの使用について詳しくは、「クイック スタート: ListView の追加」をご覧ください。FlipView とテンプレートの使用について詳しくは、「FlipView コントロールの追加」をご覧ください。次の手順は、配列でのテンプレートの使い方を示しています。
宣言を使ってテンプレートを WinJS のコントロールとして定義し、内部構造とスタイルを指定できます。テンプレートは、DIV 要素として宣言されている場合でも、DOM の一部として処理されないので、返される DOM の検索結果には含まれません。テンプレートが表示される DIV 要素を指定することも、render メソッドが独自の DIV 要素を作るようにすることもできます。 ここでは、テンプレートを使ってバインド可能な可変数のデータ オブジェクトを DIV 要素にバインドする方法について説明します。ユーザーは、ドロップダウン リストから項目を選んで、表示するオブジェクトの数を選びます。
必要条件
- 「クイックスタート: HTML 要素へのデータとスタイルのバインド」の手順を最後まで実行すると、この方法トピックの手順を実行する際に役立ちます。
手順
ステップ 1: テンプレートを使うためのプロジェクトを設定する
テンプレートを使うためのプロジェクトを設定するには、次の手順を実行します。
JavaScript を使って空の Windows ストア アプリを作成し、TemplateExample という名前を付けます。
次に示すように、default.html ファイルの BODY 要素内で、テンプレート用の DIV 要素を追加して templateDiv という ID を指定し、"WinJS.Binding.Template" という値を持つ data-win-control 属性を追加します。
<body> <div id="templateDiv" data-win-control="WinJS.Binding.Template"></div> </body>
データ オブジェクトを定義したら、テンプレートの内部構造の追加作業に戻ります。
ステップ 2: データ オブジェクトを定義し、テンプレートのフィールドにバインドする
default.js の直接起動される関数内に、複数のフィールドを含むオブジェクトを宣言します。ここでは、WinJS.Binding.define を使って、すべてのプロパティをバインド可能にします。
(function () { "use strict"; // Other app code ... // Define a Person object with bindable properties. var Person = WinJS.Binding.define({ name: "", color: "", birthday: "", petname: "", dessert: "" }); })();
テンプレートにこのオブジェクトのフィールドを表示するには、次に示すように、項目がデータ オブジェクトのフィールドに対応するリストを追加する必要があります。default.html の BODY タグ内に、次のコードを追加します。
<div id="templateDiv" data-win-control="WinJS.Binding.Template"> <div class="templateItem" data-win-bind="style.background: color"> <ol> <li><span>Name :</span><span data-win-bind="textContent: name"></span></li> <li><span>Birthday:</span><span data-win-bind="textContent: birthday"></span></li> <li><span>Pet's name: </span><span data-win-bind="textContent: petname"></span></li> <li><span>Dessert: </span><span data-win-bind="textContent: dessert"></span></li> </ol> </div> </div>
default.html のテンプレート コードの下に、テンプレートがレンダリングされる DIV 要素を追加します。
<div id="templateControlRenderTarget"></div>
ステップ 3: 表示するオブジェクトの数を制御する
この例では、3 つの Person オブジェクトをインスタンス化し、ドロップダウン リストを追加して、表示する Person オブジェクトの数をユーザーが選べるようにします。
default.html の BODY タグ内に、次のコードを追加します。
<fieldset id="templateControlObject"> <legend>Pick a name:</legend> <select id="templateControlObjectSelector"> <option value="0">Show one</option> <option value="1">Show two</option> <option value="2">Show three</option> </select> </fieldset>
default.js の直接起動される匿名関数内に、3 つの
Person
オブジェクトの配列を作ります。(function () { "use strict"; // Other app code ... // Define a Person 'class' with bindable properties. var Person = WinJS.Binding.define({ name: "", color: "", birthday: "", petname: "", dessert: "" }); // Declare an array of People objects. var people = [ new Person({name:"Bob", color:"red", birthday:"2/2/2002", petname:"Spot", dessert:"chocolate cake"}), new Person({name:"Sally", color:"green", birthday:"3/3/2003", petname:"Xena", dessert:"cherry pie"}), new Person({name:"Fred", color:"blue", birthday:"2/2/2002", petname:"Pablo", dessert:"ice cream"}), ]; })();
ドロップダウン セレクターの変更イベントにリスナーを追加します。default.js の app.onactivated イベントのハンドラー内に、次のコードを追加します。
app.onactivated = function (args) { // Other activation code ... var selector = document.querySelector("#templateControlObjectSelector"); selector.addEventListener("change", handleChange, false); }
変更イベント ハンドラーで、テンプレートを含む DIV 要素とデータを表示する場所を指定する DIV 要素を選び、テンプレート コントロールの render を呼び出します (テンプレート コントロールは、templateDiv 要素の wincontrol プロパティで取得できます)。 テンプレートに対して render を呼び出すと、データ オブジェクトの該当するフィールドがテンプレートのリスト項目にバインドされます。
function handleChange(evt) {
var templateElement = document.querySelector("#templateDiv");
var renderElement = document.querySelector("#templateControlRenderTarget");
renderElement.innerHTML = "";
var selected = evt.target.selectedIndex;
var templateControl = templateElement.winControl;
while (selected >= 0) {
templateElement.winControl.render(people[selected--], renderElement);
}
}
これで、アプリをビルドしてデバッグできるようになりました。ドロップダウン リストの項目を選ぶと、対応する数のデータ オブジェクトがアプリに表示されます。
ステップ 4: render による DIV の追加を許可する
必ずしも、事前に作成した DIV を render 関数に渡す必要はありません。DIV が指定されなかった場合は、render が新しい DIV を作ります。ただし、DOM に新しい DIV を追加する必要があります。render の戻り値は WinJS.Promise であることに注意してください。promise について詳しくは、「クイック スタート: promise の使用」をご覧ください。promise の done メソッドに、新しい DIV を追加する関数を追加します。
前の手順の while ブロックを次のように変更します。
while (selected >= 0) {
templateElement.winControl.render(people[selected--])
.done(function (result) {
renderElement.appendChild(result);
});
}
注釈
このトピックでのコードの完全なリストを次に示します。
default.html (Windows)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>TemplateExample</title>
<!-- WinJS references -->
<link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.2.0/js/base.js"></script>
<script src="//Microsoft.WinJS.2.0/js/ui.js"></script>
<!-- TemplateExample references -->
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/default.js"></script>
</head>
<body>
<div id="templateDiv" data-win-control="WinJS.Binding.Template">
<div class="templateItem" data-win-bind="style.background: color">
<ol>
<li>Name: <span data-win-bind="textContent: name"></span></li>
<li>Birthday: <span data-win-bind="textContent: birthday"></span></li>
<li>Pet's name: <span data-win-bind="textContent: petname"></span></li>
<li>Dessert: <span data-win-bind="textContent: dessert"></span></li>
</ol>
</div>
</div>
<div id="templateControlRenderTarget"></div>
<fieldset id="templateControlObject">
<legend>Pick a name:</legend>
<select id="templateControlObjectSelector">
<option value="0">Show one</option>
<option value="1">Show two</option>
<option value="2">Show three</option>
</select>
</fieldset>
</body>
</html>
default.html (Windows Phone)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>TemplateBinding</title>
<!-- WinJS references -->
<link href="/css/ui-themed.css" rel="stylesheet" />
<script src="//Microsoft.Phone.WinJS.2.1/js/base.js"></script>
<script src="//Microsoft.Phone.WinJS.2.1/js/ui.js"></script>
<!-- TemplateBinding references -->
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/default.js"></script>
</head>
<body>
<div id="templateDiv" data-win-control="WinJS.Binding.Template">
<div class="templateItem" data-win-bind="style.background: color">
<ol>
<li>Name: <span data-win-bind="textContent: name"></span></li>
<li>Birthday: <span data-win-bind="textContent: birthday"></span></li>
<li>Pet's name: <span data-win-bind="textContent: petname"></span></li>
<li>Dessert: <span data-win-bind="textContent: dessert"></span></li>
</ol>
</div>
</div>
<div id="templateControlRenderTarget"></div>
<fieldset id="templateControlObject">
<legend>Pick a name:</legend>
<select id="templateControlObjectSelector">
<option value="0">Show one</option>
<option value="1">Show two</option>
<option value="2">Show three</option>
</select>
</fieldset>
</body>
</html>
default.js (Windows および Windows Phone)
(function () {
"use strict";
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
} else {
}
// Add event handler to selector.
var selector = document.querySelector("#templateControlObjectSelector");
selector.addEventListener("change", handleChange, false);
args.setPromise(WinJS.UI.processAll());
}
};
app.start();
// Define a Person 'class' with bindable properties.
var Person = WinJS.Binding.define({
name: "",
color: "",
birthday: "",
petname: "",
dessert: ""
});
// Declare an array of People objects.
var people = [
new Person({ name: "Bob", color: "red", birthday: "2/2/2002", petname: "Spot", dessert: "chocolate cake" }),
new Person({ name: "Sally", color: "green", birthday: "3/3/2003", petname: "Xena", dessert: "cherry pie" }),
new Person({ name: "Fred", color: "blue", birthday: "2/2/2002", petname: "Pablo", dessert: "ice cream" }),
];
// Update the displayed data when the selector changes.
function handleChange(evt) {
var templateElement = document.querySelector("#templateDiv");
var renderElement = document.querySelector("#templateControlRenderTarget");
renderElement.innerHTML = "";
var selected = evt.target.selectedIndex;
var templateControl = templateElement.winControl;
while (selected >= 0) {
templateElement.winControl.render(people[selected--])
.done(function (result) {
renderElement.appendChild(result);
});
}
}
})();