ドイツ在住のMaik Michelさんが彼のブログにOracle APEXでknockout.jsを使用する方法を紹介しています。
Improve UX by using Knockout - show only functions that actually make sense興味深い内容だったので、knockout.jsのサイトで紹介されているチュートリアルのIntroductionをOracle APEXで実装してみました。
チュートリアルのページは以下から始まります。
Step1から5までありますが、最後のStep 5はまとめで実際の実装サンプルは1から4までです。
準備
Oracle APEXでknockout.jsを使用するために、ページ・プロパティのJavaScriptのファイルURLに以下を記述します。バージョンについては、将来のAPEXのバージョンで変更される可能性があります。
#JET_BASE_DIRECTORY#js/libs/knockout/knockout-3.5.1.js
ステップ1:Welcome!の実装
最初の例ではHTML要素のテキスト・ノードの更新を行っています。
knockout.jsのチュートリアルでは、以下のHTMLを記述しています。
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
Oracle APEXでは、これらの要素をタイプが表示のみのページ・アイテムとして作成することにします。
First nameの要素は、識別の名前をP1_FIRST_NAME、タイプを表示のみ、ラベルはFirst name:とします。ラベルと値が横並びになるように、外観のテンプレートにOptionalを選択します。
詳細のカスタム属性に、knockout.jsが使用するカスタム属性data-bindを指定します。
data-bind="text: firstName"
前のテキストに<strong>、後のテキストに</strong>を記述します。これはknockout.jsのチュートリアルに寄せた設定で、Oracle APEXでは、ユニバーサル・テーマで定義されている強調表示のクラスu-boldを詳細のCSSクラスに設定する方が一般的です。
デフォルトのタイプに静的を選択し、静的値としてtodoを設定します。これもknockout.jsのチュートリアルに寄せた設定です。
Last nameの要素も同様に作成します。
識別の名前はP1_LAST_NAME、ラベルはLast name:です。詳細のカスタム属性は以下になります。
data-bind="text: lastName"
ページ・プロパティのJavaScriptのファンクションおよびグローバル変数の宣言にて、ビューモデルを定義します。
function AppViewModel() {
this.firstName = "Bert";
this.lastName = "Bertington";
}
DOM要素にビューモデルをバインドするコードを、ページ・ロード時に実行に記述します。
ko.applyBindings(new AppViewModel());
以上の設定を行いページを実行します。
ページのロード時にページ・アイテムP1_FIRST_NAME、P1_LAST_NAMEの値が、それぞれビュー・モデルで定義されているBert、Beringtonに変更されています。
Step 2:Making the data editableの実装
先に作成したWelcome!のページをコピーし、Step 2の実装を始めます。
チュートリアルでは、以下のインプット・フィールドを追加しています。
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
これらの要素をタイプがテキスト・フィールドのページ・アイテムとして作成することにします。
First nameの要素は、識別の名前をP2_FIRST_NAME_VALUE、タイプをテキスト・フィールドとします。
詳細のカスタム属性のdata-bindでは、textの代わりにvalueを指定します。
data-bind="value: firstName"
詳細の前のテキスト、後のテキストの<strong>は削除します。それ以外の設定は表示のみのページ・アイテムP2_FIRST_NAMEと同じです。
Last nameの要素も同様に作成します。
属性の名前はP2_LAST_NAME_VALUE、詳細のカスタム属性は以下になります。
data-bind="value: lastName"
ページ・プロパティのJavaScriptのファンクションおよびグローバル変数の宣言にて定義されているビューモデルを変更します。
firstNameおよびlastNameにko.observableを指定し、自動的に変更を通知するようにしています。
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
}
以上の設定を行いページを実行すると、ページ・アイテムP2_FIRST_NAME_VALUE、P2_LAST_NAME_VALUEが変更されると即座にP2_FIRST_NAME、P2_LAST_NAMEに反映されることが確認できます。
今回の例ではビューモデルの定義をknockout.jsのチュートリアルに寄せましたが、Oracle APEXの一般的な実装では、ko.observableの引数として与える初期値はページ・アイテムの値となるでしょう。
コード例としては以下になります。
function AppViewModel() {
this.firstName = ko.observable(apex.items.P2_FIRST_NAME_VALUE.value);
this.lastName = ko.observable(apex.items.P2_LAST_NAME_VALUE.value);
}
Step 3:Defining computed valuesの実装
Step 2のページをコピーし、Step 3の実装を始めます。
チュートリアルでは、以下の氏名を表示するフィールドを追加しています。
<p>Full name: <strong data-bind="text: fullName"></strong></p>
この要素をタイプが表示のみのページ・アイテムとして作成することにします。
Full nameの要素は、識別の名前をP3_FULL_NAME、タイプを表示のみ、ラベルをFull name:とします。
詳細のカスタム属性に以下を設定します。
data-bind="text: fullName"
firstNameとlastNameを結合しfullNameを生成するように、ビューモデルを更新します。
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
}
以上でページを実行すると、First nameおよびLast nameを変更した時点で、Full nameが更新されることが確認できます。
Step 4:Add more behaviorの実装
Step 3のページをコピーし、Step 4の実装を始めます。
チュートリアルでは、Last nameを大文字に変更するボタンを作成します。
<button data-bind="click: capitalizeLastName">Go caps</button>
Oracle APEXでは上記をボタンとして作成します。
識別のボタン名をGO_CAPS、ラベルはGo Capsとします。動作のアクションとして動的アクションで定義を選択します。動的アクションは定義しないので、実質的にはHTTPのGETやPOSTのリクエスト発行しない、何もしないボタンになります。
詳細のカスタム属性として以下を記述することにより、ボタンをクリックするとビューモデルで定義された処理が実行されます。
data-bind="click: capitalizeLastName"
ビューモデルを更新します。Last nameを大文字に変更する処理を含めます。
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
this.capitalizeLastName = function() {
var currentVal = this.lastName(); // Read the current value
this.lastName(currentVal.toUpperCase()); // Write back a modified value
};
}
以上の設定を行いページを実行します。
Go Capsのボタンをクリックすると、Last nameが大文字に変更されることが確認できます。また、同時にFull nameの変更も確認できます。
Oracle APEXでのknockout.jsのチュートリアルの実装は以上になります。
今回作成したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/learn-knockoutjs.zip
本チュートリアルではknockout.jsのtext、value、clickの3つのバインディングを使用していますが、knockout.jsのドキュメントではこれ以外にも多数のバインディングが説明されています。
Oracle APEXでは機能として動的アクションが提供されていますが、knockout.jsの利用も良い選択肢となりそうです。
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完