バインディング
まずはバインディングを利用した例を見ていきましょう。
バインディングを利用すると、JavaScriptで定義されたオブジェクトを簡単に表示させたり、コントロールを関連付けて内容を同期させたりすることができます。
コードによるバインディング
リスト3はテキストボックスに入力したデータと、ラベルに表示されるデータをバインドした例です。
<script type="text/javascript">
Sys.Application.add_init(function() {
$create(Sys.Binding, {
source: $get("txtInputName"), path: "value",
target: $get("lblDispName"), targetProperty: "innerHTML"
});
});
</script>
<div>
<input type="text" id="txtInputName" /><br />
<span id="lblDispName"/>
</div>
Bindingオブジェクトのプロパティには、ソースとなるコントロール(source)のプロパティ(path)と、表示するコントロール(target)のプロパティ(targetProperty)を設定します。BindingオブジェクトはSys.Observerクラスを利用してターゲットとソースの変更通知の管理を行います。詳しい利用方法は後編で触れていきます。
このスクリプトを起動すると、図4のようにテキストボックスに値を入力し、テキストボックスからフォーカスが移動するタイミングでラベルにテキストボックスに入力した値が表示されます。

宣言的なバインディング
宣言的なバインディングが導入されたことで、変更時に関してはJavaScriptを自前で記述しなくてもテキストボックスの変更をラベルに通知することができるようになりました。しかし、リスト3では2つのコントロールをバインドするためのコードを記述する必要があります。リスト4はリスト3を宣言的な記法で書き換えた例です。
<!-- (1) タグの定義とバインディングの有効化 -->
<body xmlns:sys="javascript:Sys"
xmlns:binding="javascript:Sys.Binding"
sys:activate="bindingContainer">
<form id="form1" runat="server" >
<asp:ScriptManager ID="ScriptManager" runat="server">
<Scripts>
<asp:ScriptReference Name="MicrosoftAjaxTemplates.js" />
</Scripts>
</asp:ScriptManager>
<div id="bindingContainer">
<!-- (2) バインディングの定義 -->
<input type="text" id="txtInputName"
sys:attach="binding"
binding:source="{{ $get('txtInputName') }}"
binding:path="value"
binding:target="{{ $get('lblDispName') }}"
binding:targetproperty="innerHTML" /><br />
<span id="lblDispName" />
</div>
</form>
</body>
(1)タグの定義とバインディングの有効化
bodyタグではASP.NET AJAX 4.0が提供するSysオブジェクトやBindingオブジェクトをsysやbindingといった名前空間にマッピングし、sys:activateに指定されたコンテナをバインディングの対象とします。ここでsys:activate="*"とするとHTMLに含まれるすべてのコンテナに対してバインディングが有効になります。
(2)バインディングの定義
ASP.NET AJAX 4.0でHTMLの要素をバインドする場合は、sys.attach属性を利用し対象となるオブジェクトにbindingオブジェクトをattachします。つづいて、リスト3で記述したようにソースとなるコントロールのプロパティとターゲットとなるコントロールのプロパティを定義します。
DataViewを用いたWPFライクなバインディング
次にJavaScriptのオブジェクトをソースとしてバインディングを行う例をリスト5に示します。
<!-- タグの定義とバインディングの有効化 -->
<body xmlns:sys="javascript:Sys"
xmlns:dataview="javascript:Sys.UI.DataView"
sys:activate="bindingContainer">
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Name="MicrosoftAjaxTemplates.js" />
</Scripts>
</asp:ScriptManager>
<script type="text/javascript">
// ページロード時に呼び出される関数
Sys.Application.add_load(function() {
var dataSource = { name: "karua" };
$find("bindingContainer").set_data(dataSource);
});
// 値の表示ボタンクリック時にバインドしたデータを表示する関数
function dispContext() {
alert($find("bindingContainer").get_data().name);
}
// spanに表示するデータの変換を行うコンバーター
function formatName(value) {
return String.format("名前:{0}", value);
}
</script>
<div id="bindingContainer" class="sys-template"
sys:attach="dataview" >
<input type="text" value="{binding path=name}" /><br />
<span>{binding path=name, convert="formatName"}</span>
</div>
<input type="button" value="値の表示" onclick="dispContext()" />
</form>
</body>
リスト4の例とほとんど同じですが、リスト5ではページのロードタイミングでJavaScriptからDataViewオブジェクトのdataプロパティにJavaScriptのdataSource変数を設定し、inputタグとspanタグはdataSource変数のnameプロパティをバインディングしています。 (バインディングには{binding ...}といった特殊な構文を利用します。)
記述は変わりましたが、設定している内容はリスト3やリスト4と同じです。たとえばinputタグには、ソースとなるオブジェクト(dispContextメソッドで設定されたデータ)のプロパティ(path)を指定します。この場合はdataSource変数のnameプロパティを設定しています。
ASP.NET AJAX 4.0のバインディングはWPFやSilverlightのバインディングとよく似ています。Silverlightのバインディングに関しては次の記事を参照してください。
ASP.NET AJAXのバインディングもWPFやSilverlightと同じように通知の方向(Tow-Way, One-Way, One-Time)を指定したり、コンバーターを利用して値の変換を行うことができます。リスト5の例ではspanタグにはformatNameコンバーターが設定されているため、データに変更がかかったタイミングでJavaScriptのformatNameメソッドが呼び出され、「名前: + バインディングされたデータ」に変換された値が表示されます。
