Zen ページ
Zen アプリケーション内のページは、クラス %ZEN.Component.pageOpens in a new tab から派生しています。 ページ・クラスは、ブラウザで Zen ページのコンテンツを定義し、供給します。この章では、Zen ページのプログラミングについて説明します。これは、以下に示す基礎に基づいています。
-
ドキュメント "Zen の使用法"
-
このドキュメントの前の章 : “Zen アプリケーション”
この章では、上の一覧の情報を補足する詳細な技術情報を提供します。この章は、以下のトピックで構成されています。
Zen ページのコンテンツ
ページに表示するコンテンツは、そのページに属する一連の Zen コンポーネントで定義します。これは、そのページのコンポーネント・オブジェクト・モデルです。コンポーネント・オブジェクト・モデルおよびこのモデルとページの関係に関する背景情報と図は、“Zen の使用法” というドキュメントの “Zen アプリケーションの概念” の章を参照してください。
このトピックの各セクションでは、Zen ページのコンポーネント・オブジェクト・モデルを指定する方法を説明します。以下の技法リストには、詳細を説明するセクションへのリンクが含まれています。Zen ページのコンテンツは、次のように指定できます。
-
"XML を使用したページ・コンテンツの静的な定義" Zen ページ・クラス内に XData Contents という名前の XML ブロックを配置できます。
-
"表示前のページ・コンテンツの変更" %OnAfterCreatePage() コールバック・メソッドをオーバーライドして、このメソッドから各種のサーバ側メソッドを呼び出すことができます。これらのサーバ側メソッドは、コンポーネントへのポインタの取得、コンポーネントの追加、コンポーネントの変更、コンポーネントの非表示や再表示、およびコンポーネント・オブジェクト・モデルからのコンポーネントの削除を行います。
-
"表示後のページ・コンテンツの変更"ページが表示された後に、ユーザ・アクション (クリックなど) のハンドラを設定して、これらのハンドラから各種のクライアント側もしくはサーバ側メソッドを呼び出すようにします。これらのメソッドは、コンポーネントへのポインタの取得、コンポーネントの追加、コンポーネントの変更、コンポーネントの非表示や再表示、およびコンポーネント・オブジェクト・モデルからのコンポーネントの削除を行います。
また、onloadHandler() クライアント側メソッドをオーバーライドして、クライアント側で表示される前にページを変更することもできます。この JavaScript メソッドは、ページが表示される直前にクライアント側で実行されます。詳細は、“ページ用のクライアント側コールバック・メソッド” セクションのテーブルにある onloadHandler() のエントリを参照してください。
XML を使用して基本ページを定義してから、上記の方法を組み合わせて使用することで、実行時にこのページを動的に変更できます。
XML を使用したページ・コンテンツの静的な定義
Zen ページ・クラスでは、そのページで使用するコンポーネントのセットを定義した XData Contents ブロック (クラス定義に埋め込んだ XML ドキュメント) を指定できます。ページのコンテンツはプログラムを使用して定義することもできますが、ほとんどの場合、XML ブロックを使用するほうが便利です。
次の XData Contents ブロックは、ボタン・コンポーネントを 1 つ持つシンプルなページ・オブジェクトを定義します。
XData Contents [XMLNamespace="http://www.intersystems.com/zen"]
{
<page xmlns="http://www.intersystems.com/zen" title="My Page">
<button caption="Hey"/>
</page>
}
XData Contents ブロックは実行時には処理されません。その代わり、コンパイル時に XData Contents の情報を使用して、クラス・コンパイラで %CreatePage というメソッドが生成されます。このメソッドを表示するには、ページ・クラスをコンパイルし、スタジオで [他の表示] コマンドを使用して、このページ・クラスのために生成されたコードを確認します。この方法で、このメソッドを変更することはできません。%CreatePage メソッドは実行時に呼び出され、ページ・コンポーネント・モデルのコンテンツが作成されます。
XData Contents の詳細は、"Zen の使用法" の “Zen のレイアウト” と “Zen のスタイル” の章を参照してください。
XData Contents 定義で XML ネームスペースを宣言することをお勧めします。 このためには、<page> 要素で xmlns 属性を指定します。以下はその例です。
<page xmlns="http://www.intersystems.com/zen" >
カスタム・コンポーネントを追加すると、異なるネームスペースにある複数のコンポーネントの間で競合が発生する可能性が高くなります。これは、<composite> や <pane> などの他の Zen 要素でも同様です。<page> に xmlns 属性を追加すると、ネームスペースの競合を防止できます。
表示前のページ・コンテンツの変更
ページを表示する前にそのコンテンツをプログラムによって変更する必要がある場合は、%OnAfterCreatePage() コールバック・メソッドに次の例のようなコードを追加します。この例では、新しいグループ・コンポーネントを作成してから、そのページの %AddChild() メソッドを使用してそのグループをページに追加します。その後で、いくつかのコンポーネントを作成して、これらのプロパティを設定して、そのグループの %AddChild() メソッドを使用してこれらのコンポーネントをグループに追加します。
Method %OnAfterCreatePage() As %Status
{
Set tGroup = ##class(%ZEN.Component.group).%New()
Do %page.%AddChild(tGroup)
Set tBtn = ##class(%ZEN.Component.button).%New()
Set tBtn.caption = "Button 1"
Do tGroup.%AddChild(tBtn)
Set tBtn = ##class(%ZEN.Component.button).%New()
Set tBtn.caption = "Button 2"
Do tGroup.%AddChild(tBtn)
Quit $$$OK
}
キャプションやその他のラベル用として追加したテキストは、XML を使用してキャプション属性を追加する場合とは異なり、自動的にローカライズされません。ローカライズされたキャプションが必要な場合は、%OnAfterCreatePage() メソッドで $$$Text ローカライズ・マクロを呼び出す必要があります。前述の例に、これは示されていません。
<timer> などの表示されないコンポーネントは、%AddChild() の代わりに %AddComponent() を使用してページに追加できます。表示されるコンポーネントについては、%AddChildBefore() メソッドと %AddChildAfter() メソッドも使用できます。これらのメソッドには、既存の同位コンポーネントを識別する 2 番目のパラメータがあります。
プログラムでページが構成される様子を把握する最善の方法として、XData Contents を使用してページの概念を定義する任意の Zen ページ・クラスで %CreatePage メソッド用に生成されたコードを調べる方法があります。以下はその方法です。
-
スタジオでページ・クラスを開きます。
-
[ビュー]→[他の表示]、Ctrl-Shift-V、または アイコンを選択します。
-
“1” とマークされたファイルを選択して [開く] をクリックします。
-
文字列 %CreatePage を検索します。
-
メソッドをスクロールして、ページにコンポーネントがどのように追加されているか確認します。
以下のテーブルでは、ページのコンポーネント・オブジェクト・モデルを動的に操作するためのサーバ側メソッドを示しています。これらのメソッドはファイナル・メソッドであるため、オーバーライドできません。ページを含めてすべてのグループ・コンポーネントは、これらのメソッドをサポートしています。これらのメソッドは、コンポーネント・オブジェクト・モデルの任意の階層レベルにあるグループ・オブジェクトまたはページ・オブジェクトで呼び出すことができます。
メソッド | 説明 |
---|---|
%AddChild(obj) |
このページまたはグループに子コンポーネントを追加します。obj は、追加するコンポーネントへのポインタです。%AddChild() がグループ上で呼び出された場合、このメソッドは、コンポーネントをこのグループに追加するだけでなく、このグループが属しているページにも追加します。 %AddChild() を呼び出してコンポーネントをグループに追加する前に、次の条件が満たされている必要があります。
|
%AddChildAfter(obj,sib) | 機能と制限事項は %AddChild() と同じですが、子コンポーネント obj をグループに追加して、sib で指定された兄弟オブジェクトの直後の位置に配置します。sib には、グループ内の既存オブジェクトへのポインタを指定する必要があります。 |
%AddChildBefore(obj,sib) | 機能と制限事項は %AddChild() と同じですが、子コンポーネント obj をグループに追加して、sib で指定された兄弟オブジェクトの直前の位置に配置します。sib には、グループ内の既存オブジェクトへのポインタを指定する必要があります。 |
%AddComponent(obj) | obj は、ページまたはグループに追加するコンポーネントへのポインタです。<timer> などの表示されないコンポーネントを追加する場合にのみ、%AddChild() の代わりに %AddComponent() を使用します。それ以外の場合は、%AddChild() を使用します。 |
%GetChildIndex(obj) | このグループ内の子コンポーネント obj を探して、そのインデックス番号 (先頭値は 1) を返します。この子コンポーネントが見つからない場合は、-1 を返します。 |
%RemoveChild(obj) | このグループから子コンポーネント obj を削除します。このコンポーネントが見つかって削除された場合は、1 (True) を返します。 |
%RemoveChildren(flag) | このグループからすべての子コンポーネントを削除します。flag が 1 (True) の場合は、グループに動的に追加された子コンポーネントのみを削除して、XData Contents から静的に追加された子コンポーネントは保持します。 flag が省略されたか 0 (False) の場合は、このグループからすべての子コンポーネントを削除します。 |
表示後のページ・コンテンツの変更
必要に応じて、クライアント側のユーザ操作に基づいて動的にページのコンポーネントを変更することもできます。SAMPLES ネームスペースの ZENTest.DynamicComponentsTestOpens in a new tab クラスには、ユーザ入力に応えてクライアント側およびサーバ側の両方からこの処理を実行する有用な例が用意されています。 “開発プロジェクトの例” セクションでは、コンポーネントを動的にページに追加する別の例が用意されています。ユーザにコンポーネントを表示するには、そのコンポーネントを作成したうえで、該当のページの子として追加する必要があります。
コンポーネントを Zen ページ上で正常に表示するには、Zen が関連する CSS および JavaScript をロードする必要があります。パフォーマンスの向上ため、Zen ページではすべてのコンポーネントに対しての CSS および JavaScript の自動ロードは行いません。Zen ではロードするファイルの判別を、ページの表示中に呼び出される XData Content ブロックおよびメソッド (%OnAfterCreatePage() など) の解析により行います。ページへのコンポーネントの動的な追加をクライアントもしくはサーバ側メソッドで行う場合、%import プロパティを使用して、コンポーネントを指定する必要があります。これにより、Zen が必要な CSS および JavaScript ファイルをロードすることができます。Zen では冗長性のチェックを行うので、インポート・プロパティが既にロード済みのファイルを指定しても、そのファイルが 2 つ含まれることはありません。
以下のコードは、<svgFrame> および <lineChart> コンポーネントの %import プロパティを示しています。
Property %import As %ZEN.Datatype.string(MAXLEN = 1000, XMLNAME = "import")
[InitialExpression = "%ZEN.SVGComponent.svgFrame,%ZEN.SVGComponent.lineChart"];
動的に追加されたコンポーネントすべてに %import を使用していないのに、ページが正常に表示される場合でも、%import の使用は不要とは考えないでください。必要な CSS および JavaScript は、XData Content ブロックの解析の結果としてロードされたファイルに含まれている場合があります。しかし、インターシステムズではこれらの CSS および JavaScript ファイルの構成を変更する可能性を常に有しています。
以下のテーブルでは、ページのコンポーネント・オブジェクト・モデルを動的に操作するためのクライアント側メソッドを示しています。これらのメソッドはファイナル・メソッドであるため、オーバーライドできません。このページは、コンポーネント・オブジェクトを作成および削除するための以下のクライアント側メソッドをサポートしています。
メソッド | 説明 |
---|---|
createComponent(name) | 既定の zen ネームスペース内で、新しいコンポーネント・オブジェクトを作成します。name は、コンポーネント・クラスの単純な名前です ("button" など)。 |
createComponentNS(ns,name) |
ns ネームスペース内で、新しいコンポーネント・オブジェクトを作成します。name は、Zen コンポーネント・クラスの単純な名前 ("button" など)、またはカスタム・コンポーネントのパッケージとクラスの完全な名前です。 このメソッドを使用する場合、次のいずれかの規約を使用して、カスタム・コンポーネントの JavaScript のロード方法を Zen が認識できるようにすることも重要になります。
|
deleteComponent(obj,rfr,sync) |
obj で指定されたコンポーネントがあれば、それをページから削除します。 オプションの rfr (更新) パラメータが False の場合、削除後にページは更新されません。これは、後続のコードでこのような更新処理があることがわかっている場合に有用です。既定では、更新します。 オプションの sync (同期) パラメータが True の場合、削除されたコンポーネントを含むグループの更新は同期的に実行されます。既定は非同期です。 |
ページを含めてすべてのグループ・コンポーネントは、作成されたコンポーネント・オブジェクトを追加および削除するためのクライアント側メソッドをサポートしています。これらのメソッドは、コンポーネント・オブジェクト・モデルの任意の階層レベルにあるグループ・コンポーネント (ページ自体を含む) で呼び出すことができます。
メソッド | 説明 |
---|---|
addChild(obj,refresh) |
このページまたはグループに子コンポーネントを追加します。obj は、追加するコンポーネントへのポインタです。追加する前に、createComponent() または createComponentNS() を使用してそのコンポーネントを作成する必要があります。refresh が True の場合は、新しいコンポーネントの追加後にこのグループの表示内容を更新します。 |
addChildAfter(obj,sib,refresh) | 機能は addChild() と同じですが、子コンポーネント obj をグループに追加して、sib で指定された兄弟オブジェクトの直後の位置に配置します。sib には、グループ内の既存オブジェクトへのポインタを指定する必要があります。refresh が True の場合は、新しいコンポーネントの追加後にこのグループの表示内容を更新します。 |
addChildBefore(obj,sib,refresh) | 機能は addChild() と同じですが、子コンポーネント obj をグループに追加して、sib で指定された兄弟オブジェクトの直前の位置に配置します。sib には、グループ内の既存オブジェクトへのポインタを指定する必要があります。refresh が True の場合は、新しいコンポーネントの追加後にこのグループの表示内容を更新します。 |
getChildIndex(obj) | このグループ内の子コンポーネント obj を探して、そのインデックス番号 (先頭値は 01) を返します。この子コンポーネントが見つからない場合は、-1 を返します。 |
removeChild(obj) | このグループから子コンポーネント obj を削除します。このコンポーネントが見つかって削除された場合は、1 (True) を返します。 |
クライアントおよびサーバの Zen メソッド
以下のテーブルは、さまざまなタイプのメソッドについて、Zen ページ・クラスにおける使用方法の概要をまとめたものです。
可能な呼び出し元 | 実行場所 | クラス範囲 | タイミング | コード言語 | キーワード | 名前付け規約 |
---|---|---|---|---|---|---|
クライアント | クライアント | インスタンス | — | JavaScript |
ClientMethod [Language = javascript] |
myMethod |
クライアント |
サーバ (クライアント上で実行するコードを返送できるもの) |
インスタンス | 非同期 | ObjectScript、Caché Basic、Caché MVBasic | [ZenMethod] | MyMethod |
同期 | ||||||
クラス | 非同期 | |||||
同期 | ||||||
サーバ | サーバ | インスタンス | — | ObjectScript、Caché Basic、Caché MVBasic | — | %MyMethod |
クラス |
先頭が % ではない名前を持つページ・クラスで定義されたメソッドは、クライアント側ページ・オブジェクトのメソッドになります。名前の先頭文字が % であるメソッドはすべてサーバオンリーメソッドです。
ClientMethod キーワードと [Language = JavaScript] を使用して定義されたインスタンス・メソッドはすべて、クライアント・ページ・オブジェクトのクライアント側インスタンス・メソッドになります。このメソッドを呼び出すと、ブラウザ内で実行されます。
[ZenMethod] キーワード・セットを指定して定義したメソッドは、自動的にクライアント・ページ・オブジェクトのクライアント側インスタンス・メソッドになります。クライアント側メソッドを呼び出すと、そのメソッドのサーバ側バージョンが実行されます。サーバ・メソッドの実行に必要なコンテキストは自動的に提供されます。インスタンス・メソッドは、サーバ上でインスタンス・メソッドとして実行されます。該当のクライアント・オブジェクトはシリアル化された状態でサーバに送られ、インスタンス化されます。クラス・メソッドは、サーバ上でクラス・メソッドとして実行されますが、クライアント上ではインスタンス・メソッドとして呼び出されます。
同期メソッドと非同期メソッド
サーバ側メソッドは、同期的にも非同期的にも呼び出すことができます。これは、次のように極めて円滑に自動動作で実行されます。返り値のタイプが指定されているサーバ側メソッドであれば同期的に呼び出され、返り値がクライアントに返されます。返り値のタイプが指定されていないメソッドは非同期的に呼び出され、クライアントは返り値を待機しません。
この判断はすべて、CSP ハイパーイベント・ロジックで処理されるので、AJAX とは異なり、非同期呼び出しを有効にするアプリケーション・ロジックを別途指定する必要はありません。Zen では、このようにほとんどの AJAX フレームワークでは望めない手順を実行します。
非同期メソッドの主な利点は次のとおりです。
-
サーバ要求の処理中でもブラウザは動作を継続できます。
-
サーバ・メソッドを呼び出し、メッセージの表示などによってクライアントを変更できます。このメッセージは、サーバ・メソッドが完了したときにサーバ・ロジックで更新できます。
Zen コンポーネントの中には、非同期メソッドを活用しているものもあります。例えば、<dataCombo> コントロールは非同期メソッドを使用してサーバ側クエリを実行します。これにより、<dataCombo> では、クエリの実行中に loading... メッセージを表示できます。サーバからの応答が到着するとこのメッセージは置き換えられるので、クエリが短時間で実行されると、ユーザにはこのメッセージが見えないこともあります。
Zen には、True に設定することで、すべてのメソッドをその返り値の有無に関係なく、同期的に実行できるクライアント側フラグ zenSynchronousMode が用意されています。このフラグを False に設定すると、返り値を持つメソッドは同期的に実行され、それ以外のメソッドは非同期的に実行されます。このフラグを設定する手順は次のとおりです。
-
まず、zenSynchronousMode の現在の値を取得し、保存します。
-
次に、このフラグを目的の値に設定します。
-
処理の終了後、zenSynchronousMode の元の値をリストアします。
この規約のほか、すべてのコンポーネントで利用できるクライアント側メソッド refreshContents には、True または False の値を設定できる単一のオプション引数があります。このフラグは、クライアントでのコンポーネントの更新を同期的に実行するか (True)、非同期的に実行するか (False) を指定します。この引数を省略した場合の既定値は False です。
メソッド引数および返りタイプとしてのコレクション
Zen クラス・メソッドを使用してクライアントとサーバ間でコレクションを受け渡しできます。ここでは、そのための規約について説明します。リストと配列の両方がサポートされています。リストの使用例は、"Zen コンポーネントの使用法" の “Zen のグラフ” の章の “JavaScript メソッドの使用法” を参照してください。
ここで説明する規約が機能するためには、[ZenMethod] が、例にあるように ClassMethod キーワードを使用して宣言したクラス・メソッドであることが必要です。コレクションを、インスタンス・メソッドの引数や返りタイプとすることはできません。また、この方法ではリテラルのコレクションのみがサポートされています。より複雑な内容をアプリケーションで渡す必要がある場合は、そのアプリケーションで Zen クラス・オブジェクトを定義し、コレクションの代わりに使用します。
リスト
リスト・コレクションを引数としてサーバ側 Zen クラス・メソッドに渡すには、次のように、データ型として %ListOfDataTypesOpens in a new tab を使用します。
ClassMethod MyMethod(list as %Library.ListOfDataTypes) [ZenMethod]
{
Set x = list.GetAt(1)
}
このメソッドは、次のように JavaScript 配列オブジェクトを渡すことで、クライアント側から呼び出すことができます。
var list = new Array();
list[list.length] = 22;
zenPage.MyMethod(list);
サーバからリストを返すには、サーバ側 Zen クラス・メソッドの返り値として、以下のように %ListOfDataTypesOpens in a new tab を使用します。
ClassMethod MyMethod() as %Library.ListOfDataTypes [ZenMethod]
{
Set ret = ##class(%Library.ListOfDataTypes).%New()
Do ret.Insert("red")
Quit ret
}
クライアントからは、このメソッドは、0 から始まるインデックスを持つ JavaScript 配列オブジェクトを返します。以下はその例です。
var list = zenPage.MyMethod();
alert(list[0]); // should show 'red'
配列
配列コレクションを引数としてサーバ側 Zen クラス・メソッドに渡すには、次のように、データ型として %ArrayOfDataTypesOpens in a new tab を使用します。
ClassMethod MyMethod(arg as %Library.ArrayOfDataTypes) [ZenMethod]
{
Set x = arg.GetAt("item1")
}
このメソッドは、次のように JavaScript 連想配列 (JavaScript の Object) を渡すことで、クライアント側から呼び出すことができます。以下はその例です。
var arr = new Object();
arr['item1'] = 22;
zenPage.MyMethod(arr);
サーバから配列を返すには、サーバ側 Zen クラス・メソッドの返り値として、次のように %ArrayOfDataTypesOpens in a new tab を使用します。
ClassMethod MyMethod() as %Library.ArrayOfDataTypes [ZenMethod]
{
Set ret = ##class(%Library.ArrayOfDataTypes).%New()
Do ret.SetAt("red","color")
Quit ret
}
クライアントからは、このメソッドは、JavaScript 連想配列 (JavaScript の Object) を返します。以下はその例です。
var arr = zenPage.MyMethod();
alert(arr['color']); // should show 'red'
例 : クライアントとサーバの間のコレクションの受け渡し
以下の Zen ページ・クラス例では、次の動作に必要なコード規約を示しています。
-
上部のボタンをクリックすると、コレクション・オブジェクトがクライアントからサーバに送信されます。
-
下部のボタンをクリックすると、コレクション・オブジェクトがサーバから取得されて、クライアントに送信されます。
Class MyApp.Test Extends %ZEN.Component.page
{
XData Contents [XMLNamespace = "http://www.intersystems.com/zen"]
{
<page xmlns="http://www.intersystems.com/zen" title= "">
<button caption="Ship array to server"
onclick="zenPage.testClientToServer();" />
<button caption="Get array from server"
onclick="zenPage.testServerToClient();" />
</page>
}
ClientMethod testClientToServer() [ Language = javascript]
{
var list = new Array();
list[list.length] = 22;
alert(zenPage.MyClientToServer(list));
}
ClassMethod MyClientToServer(pList As %ListOfDataTypes) As %String [ZenMethod]
{
Set ^%x = pList.GetAt(1)
Quit ^%x
}
ClientMethod testServerToClient() [ Language = javascript]
{
var list = zenPage.MyServerToClient();
alert(list.join('\n'));
}
ClassMethod MyServerToClient() As %ListOfDataTypes [ZenMethod]
{
Set pList = ##class(%ListOfDataTypes).%New()
Do pList. Insert("RED")
Do pList. Insert("GREEN")
Do pList. Insert("BLOOP")
Quit pList
}
}
埋め込み HTML および JavaScript
このサンプルの %DrawHTML メソッドは、Zen のドキュメントおよびサンプル・コード全体で共通して使用している構文、つまりキーワード &html の後に山括弧 <> で囲まれた HTML 文が続く構文を使用しています。これは、埋め込み HTML 文の ObjectScript 構文です。
Method %DrawHTML()
{
&html<<div class="MyComponent">Message</div>>
}
ObjectScript は、[ZenMethod] キーワードでマーク付けされたサーバ側メソッドの 埋め込み JavaScript 文に、類似した構文を提供します。これらのメソッドの中で、キーワード &js の後に山括弧 <> で囲んだ JavaScript 文を記述できます。Zen は、サーバでメソッドを実行する一方、JavaScript コードのスニペットを見つけ、このスニペットを実行するためクライアントに送信します。括弧内で使用されている、埋め込み JavaScript を囲むすべての角括弧をエスケープする必要があることに注意してください。以下はその例です。
Method BtnClickMe() [ZenMethod]
{
&js<alert('Client Method');>
Quit
}
&html<> および &js<> の他に、SQL 文を記述するための &sql<> 規約もあります。これらの各 ObjectScript 言語の規約には、Zen アプリケーションおよびページ・クラスの中にコードのスニペットを囲む便利な方法が用意されています。構文の詳細は、"Caché ObjectScript リファレンス" の & 記号の定義を参照してください。
“&js< ...” “ >” は、同期モードで動作していて、ドキュメント・オブジェクト・モデル (DOM) 同期が発生していない ClassMethods と対話している場合にのみ使用するようにしてください。
インスタンス・メソッドで、DOM 内の要素を変更している場合、このコードは、ハイパーイベントによって返され、関数にバンドルされて、返されるとすぐにブラウザで実行されます。その後、DOM が発生し、その関数によって加えられた変更はすべて上書きされます。それらの関数を非同期で呼び出している場合には、関数が予想した順番で実行されないおそれもあります。
サーバ側メソッドの自動データ型変換
サーバ側メソッドを呼び出したときにデータ型変換を行うメカニズムは以下のように機能します。
-
サーバ側メソッドを呼び出すと、%ZEN.Datatype.booleanOpens in a new tab 引数はすべて、クライアント側の True/False からサーバ側の 1/0 に変換されます。
-
サーバ側メソッドの返り値のタイプが %ZEN.Datatype.booleanOpens in a new tab である場合、その返り値はクライアント側の True/False の値に変換されます。
-
サーバ側メソッドの返り値のタイプが %ZEN.Datatype.listOpens in a new tab である場合、その返り値はクライアント側配列に変換されます。
-
サーバ側メソッドの返り値のタイプが数値である場合、そのメソッドが "" を返した場合を除き、その返り値はクライアント側の数値に変換されます。
-
オブジェクト値の引数をとるメソッドは、その引数を指定しない場合や NULL である場合でも問題なく機能します。
サーバ側メソッド
このセクションの各トピックでは、サーバ側で実行される重要なページ・メソッドとコンポーネント・メソッドについて説明します。
ページ用のサーバ側コールバック・メソッド
コールバック・メソッドは Caché クラスでユーザが記述したメソッドで、メソッド呼び出しではなく、特定のシステム・イベントによりトリガされます。コールバック・メソッドを区別するために、Caché 開発者は次の形式で名前を付けています。
%OnEvent
ここで、キーワード Event はコールバックをトリガする Caché システム・イベントを表します。イベントがコールバック・メソッドをサポートする場合、そのイベントを制御するメソッドは、クラスにコールバック・メソッドが存在すれば自動的にそのメソッドを実行します。
コールバック・メソッドを明示的に呼び出して実行しないでください。クラスにメソッドを実装して、適切な条件下で Caché からこのメソッドが自動的に呼び出されるようにします。イベントが発生してもクラスで何も実行されないようにするには、対応するコールバック・メソッドの実装やオーバーライドをすべて省略します。
%ZEN.Component.pageOpens in a new tab から派生した HTML ページを描画すると、ページのコンテンツがブラウザに送信される前に、このサーバで実行する多数のコールバック・メソッドが呼び出されます。以下のテーブルは、これらのメソッドの一覧です。ページ・クラスでこれらのメソッドをオーバーライドし、ページの動作を制御できます。
コールバック・メソッド | 説明 |
---|---|
%OnBeforeCreatePage() | このクラス・メソッドは、サーバ側ページ・オブジェクトが作成される直前に呼び出されます。 |
%OnCreatePage() | このインスタンス・メソッドは、サーバ側ページ・オブジェクトが作成された直後、その子コンポーネントが 1 つも作成されていないときに呼び出されます。 |
%OnAfterCreatePage() | このインスタンス・メソッドは、サーバ側ページ・オブジェクトとその事前定義された子コンポーネントがすべて作成された後で呼び出されます。 このメソッドをサブクラスでオーバーライドして、ページ・オブジェクト・モデルにある項目の追加、削除、修正や、コントロール値の指定などができます。 |
%OnDrawHTMLHead() | このインスタンス・メソッドは、ページの HTML のレンダリングで、HTML HEAD セクションのレンダリングが終了する直前に呼び出されます。これにより、必要に応じて、ページの HEAD セクションにコンテンツを追加できます。 |
%OnDrawHTMLBody() | このインスタンス・メソッドは、ページの HTML BODY セクションの先頭近く (いずれかの子コンポーネントをレンダリングする前) でページの HTML をレンダリングしているときに呼び出されます。これにより、必要に応じて、ページの BODY セクションにコンテンツを追加できます。 |
%OnMonitorBackgroundTask(...) | このクラス・メソッドは、クライアントがバックグラウンド・タスクの進行状況をチェックしてそのタスクがまだ実行中であったときに呼び出されます。詳細は、“サーバでのバックグラウンド・タスクの実行” を参照してください。 |
%OnFinishBackgroundTask(...) | このクラス・メソッドは、クライアントがバックグラウンド・タスクの進行状況をチェックしてそのタスクが完了していたときに呼び出されます。詳細は、“サーバでのバックグラウンド・タスクの実行” を参照してください。 |
ページ用のサーバ側メソッド
ページ・クラスに含まれているいくつかのサーバ側メソッドは、サーバ上でコンポーネント・オブジェクト・モデルを操作したり、サーバ上でバックグラウンド・タスクを実行したり、フォームの送信を処理したりするのに役立ちます。これらのメソッドはファイナル・メソッドであるため、オーバーライドできません。
以下のテーブルは、汎用サーバ側メソッドの一覧です。コンポーネント・オブジェクト・モデルを変更するためのサーバ側ページ・クラス・メソッドの一覧は、“サーバでのページ・コンテンツの動的な定義” を参照してください。
メソッド | 説明 |
---|---|
%GetComponent(index) | index で指定されたシステム割り当てインデックス番号を持つコンポーネント・オブジェクトへのポインタを返します。 |
%GetComponentById(id) | id で指定されたユーザ割り当て ID を持つコンポーネント・オブジェクトへのポインタを返します (この id 値は XData Contents または他のユーザ・コード内でそのコンポーネント・オブジェクトに割り当てられたものです)。 |
%GetComponentByName(name) | name で指定されたユーザ割り当て名を持つコンポーネント・オブジェクトへのポインタを返します (この name 値は XData Contents または他のユーザ・コード内でそのコンポーネント・オブジェクトに割り当てられたものです)。このページ上で複数のコンポーネントが同じ名前を持っている場合は、最初に見つかったものを返します。 |
%GetValueById(id) | id で指定されたユーザ割り当て ID を持つコントロール・コンポーネントの value を返します。 |
%GetValueByName(name) | name で指定されたユーザ割り当て名を持つコントロール・コンポーネントの value を返します。このページ上で複数のコンポーネントが同じ名前を持っている場合は、最初に見つかったものを返します。 |
%EndBackgroundMethod() | バックグラウンド・タスクとして呼び出されたメソッドの後にクリーンアップを実行します。詳細は、“サーバでのバックグラウンド・タスクの実行” を参照してください。 |
%RunBackgroundMethod(...) | メソッドをバックグラウンド・タスクとして呼び出します。このメソッドはバックグラウンドで実行されますが、Zen ページはこのメソッドが復帰するまで待機しません。詳細は、“サーバでのバックグラウンド・タスクの実行” を参照してください。 |
%SetBackgroundMethodStatus(...) | このメソッドは、バックグラウンドで実行中のメソッドから呼び出して、その実行中のメソッド自体のステータス情報を更新できます。 詳細は、“サーバでのバックグラウンド・タスクの実行” を参照してください。 |
%SetErrorById(id, msg) | コンポーネントのエラー・メッセージを設定します。id には、XData Contents または他のユーザ・コード内でこのコンポーネントに割り当てられた ID を指定します。msg にはエラー・メッセージを指定します。 |
%SetErrorByName(name, msg) | name で指定されたユーザ割り当て名を持つコンポーネントのエラー・メッセージを設定します。msg にはエラー・メッセージを指定します。 |
%SetValueById(id) | id で指定されたユーザ割り当て ID を持つコントロール・コンポーネントの value を設定します。 |
%SetValueByName(name) | name で指定されたユーザ割り当て名を持つコントロール・コンポーネントの value を設定します。 |
%SetValuesByName(array) | コントロール・コンポーネントのセットの値を設定します。array には、このセット内の各コントロール・コンポーネントのユーザ割り当て name 値を添え字とする値の配列を指定します。 |
サーバでのバックグラウンド・タスクの実行
Zen ページからバックグラウンド・ジョブを起動し、そのページ内でジョブの進捗状況を追跡するメカニズムがあります。このメソッドはバックグラウンドで実行されますが、Zen ページはこのメソッドが復帰するまで待つことなく、ユーザが Zen アプリケーションの操作を続行することを許可します。これは、あるページで、実行時間が長いタスクを開始する必要があり、このタスクの完了を待っている間、クライアントに何らかのフィードバックを提供する場合に便利です。バックグラウンド・タスクを実行すると、Zen ページが通常より早くタイムアウトすることが防止されます。その理由は、Zen ページに対して指定できる最大タイムアウトは、一部の長時間実行されるタスクが完了するまでにかかる時間より短い可能性があるからです。この Zen 機能を使用するには、製品ライセンスがインストールされている必要があります。
Zen ページ・クラスには backgroundTimerInterval プロパティがあります。これは、このページにより起動されたバックグラウンド・タスクのステータスをチェックするためにトリガされるタイマ・イベントの間隔をミリ秒単位で指定したものです。既定値は 1000 です。
以下のテーブルでは、バックグラウンド・タスクをサポートするサーバ側メソッドを説明しています。これらのメソッドは、%ZEN.Component.pageOpens in a new tab から継承する任意のクラスで使用できます。
メソッド | 説明 |
---|---|
%EndBackgroundMethod() |
バックグラウンド・タスクとして呼び出されたメソッドの後にクリーンアップを実行します。これにより、そのバックグラウンド・タスクについて保持されていたすべてのステータス情報が削除されます。 このメソッドはファイナル・メソッドです。このメソッドをオーバーライドすることはできません。 |
%OnFinishBackgroundTask(id) |
このサーバ側コールバック・メソッドをオーバーライドすることで、クライアントがバックグラウンド・タスクの進行状況をチェックしてそのタスクが完了していたときのページの動作を制御できます。このメソッドの一般的な用途は、完了メッセージなどによってページを更新するための JavaScript を返送することです。 |
%OnMonitorBackgroundTask(id,status,val) |
このサーバ側コールバック・メソッドをオーバーライドすることで、クライアントがバックグラウンド・タスクの進行状況をチェックしてそのタスクがまだ実行中であったときのページの動作を制御できます。このメソッドの一般的な用途は、クライアント上の進捗バーを更新するための JavaScript を返送することです。 このコールバックが呼び出されると、id、status、および val という引数がこのコールバックに自動的に渡されます。id はバックグラウンド・タスクのジョブ ID を示す文字列、status は現在のジョブ・ステータスを示す文字列、val はバックグラウンド・タスクの完了率 (0 ~ 100 のパーセント値) を示す %FloatOpens in a new tab 値です。 |
%RunBackgroundMethod(method,arg1,arg2,...) |
バックグラウンド・ジョブを開始して、この Zen ページのクラス・メソッドを実行します。%RunBackgroundMethod() は %StatusOpens in a new tab 値を返し、以下の 1 つ以上の引数を受け取ることができます。
Zen で一度に監視できるバックグラウンド・タスクは 1 つのみです。前のバックグラウンド・タスクの実行中に %RunBackgroundMethod() が呼び出された場合は、この新しいメソッドが現在の監視対象タスクになります。前のタスクは完了するまで実行されますが、その完了はクライアントに通知されません。 このメソッドはファイナル・メソッドです。このメソッドをオーバーライドすることはできません。 |
%SetBackgroundMethodStatus(msg,val) |
このメソッドを、バックグラウンドで実行中のメソッドから呼び出して、その実行中のメソッド自体のステータス情報を更新できます。%SetBackgroundMethodStatus は値を返さず、以下の 2 つの引数を取ります。
このメソッドはファイナル・メソッドです。このメソッドをオーバーライドすることはできません。 |
コンポーネントおよびページ用のサーバ側コールバック・メソッド
以下のテーブルでは、コンポーネント (ページ自体を含む) でサポートされているサーバ側コールバック・メソッドを一覧表示して説明しています。これらのメソッドは、定義されている場合、特定のイベントへの応答として呼び出されます。これらのメソッドは、カスタム・コンポーネントを記述している場合などに実装またはオーバーライドできます。
コールバック・メソッド | 説明 |
---|---|
%OnDrawEnclosingDiv() | このサーバ側コールバック・メソッドは、表示ページ上でこのコンポーネントを囲む HTML <div> 要素の追加の属性が含まれた文字列を返す必要があります。返された文字列の先頭に必ず空白文字を挿入して、新しい %OnDrawEnclosingDiv() 属性が同じ <div> 上の他の属性と競合することを回避してください。 |
クライアント側メソッド
このセクションの各トピックでは、クライアント側で実行される重要なページ・メソッドとコンポーネント・メソッドについて説明します。
ページ用のクライアント側コールバック・メソッド
クライアント側ページ・オブジェクト zenPage は、多数のコールバック・メソッドを継承します。以下のテーブルでは、これらのメソッドを一覧表示して説明しています。これらは JavaScript メソッドであり、定義しておくと、特定のイベントへの応答として呼び出されます。これらのメソッドは、カスタム・コンポーネントを記述している場合などに実装またはオーバーライドできます。
コールバック・メソッド | 説明 |
---|---|
onkeydownHandler(evt) | このクライアント側ページ・メソッドは、存在している場合、ページ上で keydown イベントが発生したときに呼び出されます。evt は zenEvent オブジェクトであり、このオブジェクトは DOM の window.event データ構造と直接的に類似しています。詳細は、“クライアント側の関数、変数、およびオブジェクト” セクションで zenEvent の説明を参照してください。 |
onkeyupHandler(evt) | このクライアント側ページ・メソッドは、存在している場合、ページ上で keyup イベントが発生したときに呼び出されます。evt は zenEvent オブジェクトであり、このオブジェクトは DOM の window.event データ構造と直接的に類似しています。詳細は、“クライアント側の関数、変数、およびオブジェクト” セクションで zenEvent の説明を参照してください。 |
onlayoutHandler(load) | このクライアント側ページ・メソッドは、定義されている場合、ページが初めてロードされたときおよびページのサイズが変更されるたびに呼び出されます。このメソッドがロード時に呼び出された場合は、load は True であり、それ以外の場合は False です。 |
onloadHandler() | このクライアント側ページ・メソッドは、定義されている場合、クライアント・ページのロードが完了したときに呼び出されます。このメソッドは、ページの HTML onload イベントによってトリガされます。 |
onlogoutHandler() |
このクライアント側ページ・メソッドが定義されており、このページの AUTOLOGOUT パラメータが 1 (True) に設定されている場合は、このメソッドはこのページのログアウト・タイマが始動したときに呼び出されます。それ以降の動作は、このメソッドの返り値に応じて異なります。
|
onoverlayHandler(index) | このクライアント側ページ・メソッドは、存在している場合、オーバーレイ付きのコンポーネントがクリックされたときに呼び出されます。index の値には、このコンポーネントを識別するために内部で使用される、システム側で割り当てられたインデックス番号を指定します。繰り返しグループの中のコンポーネントの場合、ドットと、その後に繰り返しグループの中のこのコンポーネントの位置を示す 1 から始まる番号を続けて、index に含めることができます。アプリケーションは index の値を使用できますが、設定してはいけません。 |
onPopupAction(...) | このクライアント側コンポーネント・メソッドは、存在している場合、Zen ポップアップ・ウィンドウでこのページが親として指定されており、このウィンドウでその後に何らかのアクションが実行されたときに呼び出されます。このページは、親コンポーネントが指定されていないポップアップ・ウィンドウの既定の親です。"Zen コンポーネントの使用法" の “ポップアップ・ウィンドウとダイアログ” の章にある “ポップアップ・ウィンドウ” を参照してください。 |
onresizeHandler() | このクライアント側ページ・メソッドは、定義されている場合、クライアント・ページのサイズが変更されたときに呼び出されます。このメソッドは、ページの HTML onresize イベントによってトリガされます。 |
onServerMethodCall(method) | このクライアント側ページ・メソッドは、実装されている場合、ページ・クラス内のサーバ・メソッドが呼び出される直前に呼び出されます。method にはこのサーバ・メソッドの名前を指定します。詳細および例は、“サーバ側メソッド実行時のクライアントへの通知” を参照してください。 |
onServerMethodError(err) | このクライアント側のページ・メソッドは、実装されている場合、サーバ・メソッド呼び出しがサーバからのエラーを返すたびに呼び出されます。err にはエラー・メッセージが含まれています。詳細および例は、“サーバ側メソッド実行時のクライアントへの通知” を参照してください。 |
onServerMethodReturn(method) | このクライアント側ページ・メソッドは、実装されている場合、ページ・クラス内のサーバ・メソッドが処理された直後に呼び出されます。method にはこのサーバ・メソッドの名前を指定します。詳細および例は、“サーバ側メソッド実行時のクライアントへの通知” を参照してください。 |
onunloadHandler() |
このクライアント側ページ・メソッドは、定義されている場合、クライアント・ページがアンロードされる直前に呼び出されます。このメソッドは、ページの HTML onbeforeunload イベントによってトリガされます。 onunloadHandler メソッドが文字列値を返す場合、ユーザがそのページから移動したり、そのページを更新しようとすると、確認ダイアログが表示されます。ダイアログには、onunloadHandler メソッドの返り値に指定した文字列が表示されます。 onunloadHandler メソッドがない場合、return 文がない場合、返り値がない場合、True または False を返す場合、または文字列以外の値を返す場合は、ユーザがそのページから移動したり、そのページを更新しても確認ダイアログは表示されません。 |
サーバ側メソッド実行時のクライアントへの通知
サーバ・メソッドを呼び出す前後に Zen ページにそれを通知できます。サーバ・メソッドを呼び出す前に通知するには、Zen ページ・クラスでクライアント側 JavaScript メソッドの onServerMethodCall 抽象メソッドを実装する必要があります。次に例を示します。
ClientMethod onServerMethodCall(method) [ Language = javascript ]
{
alert('Call: ' + method);
}
サーバ・メソッドがクライアントにコードを返した直後に通知するには、Zen ページでクライアント側 JavaScript メソッドの onServerMethodReturn 抽象メソッドを実装する必要があります。次に例を示します。
ClientMethod onServerMethodReturn(method) [ Language = javascript ]
{
alert('Return: ' + method);
}
サーバ・メソッドがエラーを返すときに通知するには、Zen ページでクライアント側 JavaScript メソッドの onServerMethodError 抽象メソッドを実装する必要があります。次に例を示します。
ClientMethod onServerMethodError(error) [ Language = javascript ]
{
alert('Return: ' + error);
}
ページ用のクライアント側メソッド
クライアント側ページ・オブジェクトである zenPage は、クライアント側プログラミングに役立つ多数の JavaScript メソッドを継承します。前の “クライアント側ページのコールバック・メソッド” セクションで説明したメソッドとは異なり、これらのメソッドはファイナル・メソッドであるためオーバーライドできません。
以下のテーブルは、汎用クライアント側メソッドの一覧です。コンポーネント・オブジェクト・モデルを変更するためのクライアント側ページ・クラス・メソッドの一覧は、“クライアントでのページ・コンテンツの動的な定義” を参照してください。
メソッド | 説明 |
---|---|
cancelPopup() | 他のアクションは実行せずに、現在のポップアップ・ウィンドウを閉じます。"Zen コンポーネントの使用法" の “ポップアップ・ウィンドウとダイアログ” の章にある “ポップアップ・ウィンドウ” を参照してください。 |
endModal() | 現在モーダル・グループがある場合、それを非表示にします。"Zen コンポーネントの使用法" の “ポップアップ・ウィンドウとダイアログ” の章にある “モーダル・グループ” を参照してください。 |
fireOnLoadEvent() | onload イベントが定義されているページ上のすべてのコンポーネントについて onload イベントを発行します。Zen は、ページの内部階層に従ってこれらのイベントを逆順序で発行するため、ページの onload イベントを最後に発行します。 |
fireOnResizeEvent() | ページで onresize イベントが定義されている場合は、ページについてこのイベントを発行します。 |
fireOnUnloadEvent() | onunload イベントが定義されているページ上のすべてのコンポーネントについて onunload イベントを発行します。いずれかのコンポーネントの onunload ハンドラが文字列値を返す場合は、Zen は、その文字列値をページの onbeforeunload ハンドラの返り値として使用します。 |
firePopupAction(...) | このポップアップの親ウィンドウにユーザ・アクションが実行されたことを通知します。詳細は、"Zen コンポーネントの使用法" の “ポップアップ・ウィンドウとダイアログ” の章にある “ポップアップ・ウィンドウ” を参照してください。 |
getComponent(index) | index で指定されたインデックス番号を持つコンポーネントをページ上で検索します。このインデックス番号は、このコンポーネントを内部で識別するためにシステムによって割り当てられた番号です。繰り返しグループの中のコンポーネントの場合、ドットと、その後に繰り返しグループの中のこのコンポーネントの位置を示す 1 から始まる番号を続けて、index に含めることができます。アプリケーションは index の値を使用できますが、設定してはいけません。 |
getComponentById(id,tuple) |
id 値を指定してページからコンポーネントを検索します。繰り返しグループの中のコンポーネントの場合、オプションの tuple 番号は、グループ内でのこのコンポーネントの位置を示します (先頭は 1)。 tuple が不要な場合は、zen という JavaScript 関数を getComponentById() の省略形として使用できます。以下が使用できます。 zen(id) は以下の代わりとして使用できます。 zenPage.getComponentById(id) |
gotoPage(url) | ブラウザの場所を指定された新しい URI に設定します。gotoPage を使用して新しいページに移動することで、それらの URI が正しくエンコードされていることを確認できます。 |
launchPopupWindow(...) | ポップアップ・ウィンドウを開きます。詳細は、"Zen コンポーネントの使用法" の “ポップアップ・ウィンドウとダイアログ” の章にある “ポップアップ・ウィンドウ” を参照してください。 |
setComponentId(obj,id) | obj で指定されたコンポーネントがあれば、その id 値を変更します。 |
setTraceOption(name,flag) | このクライアント・メソッドを使用すると、クライアント側のトレース・フラグを有効または無効にできます。name にはトレース・オプションの名前を指定します。name に指定できる値は、events (クライアント・イベントのトレース)、js (サーバから返された JavaScript の表示)、または serialize (オブジェクト・シリアル化の表示) です。flag が True の場合は指定されたオプションが有効になり、False の場合は無効になります。 |
startModal(obj) | コンポーネントをモーダル・グループとして表示します。あるいは、<modalGroup> コンポーネントの show メソッドを使用します。"Zen コンポーネントの使用法" の “ポップアップ・ウィンドウとダイアログ” の章にある “モーダル・グループ” を参照してください。 |
コンポーネントおよびページ用のクライアント側コールバック・メソッド
コンポーネント (ページ自体も含む) は、いくつかのコールバック・メソッドを継承します。以下のテーブルでは、これらのメソッドを一覧表示して説明しています。これらは JavaScript メソッドであり、定義しておくと、特定のイベントへの応答として呼び出されます。これらのメソッドは、カスタム・コンポーネントを記述している場合などに実装またはオーバーライドできます。
コールバック・メソッド | 説明 |
---|---|
onPopupAction(...) |
このメソッドは、存在している場合、Zen ポップアップ・ウィンドウでこのコンポーネントが親として指定されており、このウィンドウでその後に何らかのアクションが実行されたときに呼び出されます。 詳細は、"Zen コンポーネントの使用法" の “ポップアップ・ウィンドウとダイアログ” の章にある “ポップアップ・ウィンドウ” を参照してください。 |
onEndModalHandler(zindex) | このメソッドは、存在している場合、このコンポーネントがモーダル状態から脱しようとしていることが通知される際に呼び出されます。つまり、このコンポーネントはディスプレイの最前面に配置されなくなります。呼び出し元は、ブラウザで表示されている他のコンポーネントを基準にした標準層にこのコンポーネントが戻ることを保証するのに十分な小ささの zindex 値を提供します。詳細は、"Zen コンポーネントの使用法" の “ポップアップ・ウィンドウとダイアログ” の章にある “モーダル・グループ” を参照してください。 |
onRefreshContents() | このコールバックは、存在している場合、新しい HTML がサーバから refreshContents メソッドに配信された直後に、このメソッドによって呼び出されます。 |
onStartModalHandler(zindex) |
このメソッドは、存在している場合、このコンポーネントがモーダル状態になろうとしていることが通知される際に呼び出されます。つまり、このコンポーネントはディスプレイの最前面に配置されます。呼び出し元は、ブラウザで現在表示されている他のすべてのコンポーネントより前面にこのコンポーネントが配置されることを保証するのに十分な大きさの zindex 値を提供します。 詳細は、"Zen コンポーネントの使用法" の “ポップアップ・ウィンドウとダイアログ” の章にある “モーダル・グループ” を参照してください。 |
コンポーネントおよびページ用のクライアント側メソッド
ページにある各コンポーネント (ページ自体を含む) は、多数の便利な JavaScript メソッドを継承します。以下のテーブルは、これらのメソッドの一覧です。このテーブルにはない専用のメソッドも持つコンポーネントもあります。前の “クライアント側ページのコールバック・メソッド” セクションで説明したメソッドとは異なり、これらのメソッドはファイナル・メソッドであるためオーバーライドできません。これらのメソッドは、ページ・クラスから、またはここで指定されたカスタム・コンポーネント・クラスから呼び出すことができます。
メソッド | 説明 |
---|---|
findElement(id) | このコンポーネントと関連付けられた HTML 要素を取得します。id には、Zen ページ・クラスでこのコンポーネントに指定した id 値を指定します。 |
getEnclosingDiv() | 特定のコンポーネントを囲むために使用する HTML div 要素を取得します。 |
getLabelElement() | このコンポーネントのラベルを表示する HTML 要素を取得します。 |
getHidden() | コンポーネントが現在非表示になっている場合は True を返し、それ以外の場合は False を返します。 |
getHintElement() | このコンポーネントのヒント・テキストを表示する HTML 要素を取得します。 |
getProperty(name, key) | name で指定されたコンポーネント・プロパティの値を返します。オプション・パラメータの key は、コレクションなどのプロパティが特定の値を検索するためにキーを必要とする場合に便利です。 |
getSettings(settings) | このコンポーネントの名前付きプロパティのセットを取得します。getSettings は、このメソッドの引数 (settings) である連想配列内のプロパティ名のリストを返します。その後で、これらのプロパティ名を getProperty や setProperty の引数として使用して、プロパティ値を取得したり変更したりできます。 |
getValue() | (コントロールのサブクラスの場合のみ)。コントロールの値を取得します。これは、このコンポーネントで getProperty('value') を呼び出すことと同じです。 |
invokeSuper(method, args) | method で指定されたメソッドのスーパー・クラス実装を呼び出します。args には、この指定されたメソッドの引数を JavaScript 配列として指定します。 |
isOfType(type) | あるコンポーネントが別のコンポーネントのサブクラス (タイプ) であるかどうかを判定します。入力引数 type には、form や control などの単純なコンポーネント・クラス名を指定します。 |
refreshContents(flag) |
このコンポーネントを定義する HTML の再生成要求をサーバに発行します。flag が True に設定されており、遅延モードが有効でない場合は、コンポーネントを同期的に更新します。 refreshContents には、ブラウザ・ページ上のコンポーネントを再表示するという効果があります。<tablePane> コンポーネントの場合は、代わりに executeQuery() を使用します。 |
setHidden(flag) | flag が True に設定されている場合は、コンポーネントが非表示になるように設定して、このコンポーネントの onhide コールバックを呼び出します。 flag が False に設定されている場合は、コンポーネントが表示されるように設定して、onshow コールバックを呼び出します。 |
setProperty(name, val) | コンポーネントのプロパティの値を設定します。name にはプロパティ名を指定します。val には値を指定します。 |
setPropertyAll(name, val) | グループ・コンポーネントおよびそのすべての子コンポーネントのプロパティの値を設定します。name にはプロパティ名を指定します。val には値を指定します。無効化されたプロパティについては、setPropertyAll() は機能しないため、代わりに setProperty() を使用してください。 |
setValue(val) | (コントロールのサブクラスの場合のみ)。コントロールの値を設定します。これは、このコンポーネントで setProperty('value',val) を呼び出すことと同じです。 |
startProgressBar(div) | このコンポーネントの表示領域内で進捗バーの表示を開始します。これは、サーバから提供される値を更新するコンポーネントの場合に便利です。div が指定されている場合、進捗バーはその HTML div に格納されます。 |
stopProgressBar() | 進捗バーで使用されているタイマを停止します。 |
クライアントおよびサーバの Zen プロパティ
先頭が % ではない名前を持つ Zen ページ・クラスで定義されたプロパティは、クライアント側ページ・オブジェクトのプロパティにもなります。これらのクライアント側プロパティは、ページの %DrawHTML メソッドが呼び出される直前までこれらのプロパティがサーバ側で保持していた値に初期化されます。
ページが表示される前にこれらのページ・プロパティに値を入力する場合、ページ・クラスのプロパティには、以下のいずれかの方法で初期値を設定できます。
-
以下のように、ページ・クラスの定義でプロパティの InitialExpression を定義します。
Property dayList As %ZEN.Datatype.caption [ InitialExpression = "Sun,Mon,Tue,Wed,Thu,Fri,Sat" ];
-
コールバック・メソッドである %OnCreatePage または %OnAfterCreatePage でプロパティを設定します。
サーバ側メソッドでは、通常のドット構文を使用すれば、クラス・プロパティの値を直接取得および設定できます。以下はその例です。
Method serverInstanceMethodCreate() [ ZenMethod ]
{
#; create
Set group = %page.%GetComponentById("group")
If '$IsObject(group) {
&js<alert('Unable to find group.');>
Quit
}
Set count = group.children.Count()
Set cal = ##class(%ZEN.Component.calendar).%New()
Set cal.id = "NewCal"_count
Do group.%AddChild(cal)
Set btn = ##class(%ZEN.Component.button).%New()
Set btn.id = "NewBtn"_count
Set btn.caption = "New Button"
Do group.%AddChild(btn)
Set btn = ##class(%ZEN.Component.text).%New()
Set btn.label = "Hey"
Do group.%AddChild(btn)
}
クライアントとサーバ間で値を適切に同期するために、クライアント側メソッドでプロパティ値に直接アクセスしないでください。該当のコンポーネント・クラスに用意されている取得と設定の各メソッドを使用する必要があります。単一の値のみを持つプロパティでは、getProperty メソッドと setProperty メソッドを使用します。以下はその例です。
var index = table.getProperty('selectedIndex');
または以下のようにします。
var svg = zen('svgFrame');
svg.setProperty('layout','');
svg.setProperty('editMode','drag');
getProperty と setProperty の両メソッドを、getValue および setValue の両メソッドと混同しないようにしてください。これらは、コントロール・コンポーネントの value を取得および設定するメソッドであり、他のどのコンポーネントのプロパティにも適用できません。
Zen コンポーネントのプロパティに割り当てられる値には、制限があります。DOM 内で 0 ~ 10 の数値を持つ ASCII 文字を含む値を使用することはできません。それらの文字は、通常、ObjectScript コードで数値を持つ $CHAR ($C) 関数を使用して表します (例 : $C(1)、$C(4) など)。それらの特殊文字は、Zen シリアル化コード内の区切り文字に使用するために予約されています。そのため、Zen コンポーネント・プロパティの値に ASCII 文字 0 ~ 10 のいずれかが使用されている場合、Zen でページを非シリアル化するときにエラーが発生します。
多次元プロパティは、標準 Zen ページのプロパティとしてはサポートされていません。リストや配列を使用するか、JSON を経由すると、同じ結果が得られます。
Zen ページ・クラスのパラメータ
ページの動作を制御するためにページ・クラスが使用できるクラス・パラメータは多数あります。このセクションでは、その中で最も役立つものを紹介します。その他のものについては、オンライン・クラス・ドキュメントで説明しています。
関連付けられているアプリケーションのパッケージ名とクラス名。
1 (True) の場合は、このページのセッションが無効になると、ページの更新が実行されます。0 (False) の場合、これは行われません。既定値は 1 です。
AUTOLOGOUT が 1 の場合、サーバ・セッションの有効期限が切れる頃にページを再ロードするタイマを設定する JavaScript が Zen ページで生成されます。また、サーバへの呼び出しのたびにクライアントの自動ログアウト・タイマがリセットされるコードも生成されます (サーバは既にセッション・タイムアウトをリセットしています)。AUTOLOGOUT が 0 の場合、これらのいずれのコードも生成されません。
onlogoutHandler クライアント側ページ・メソッドが定義されており、AUTOLOGOUT が 1 (True) に設定されている場合は、onlogoutHandler はこのページのログアウト・タイマが始動するたびに呼び出されます。それ以降の動作は、次のように、このメソッドの返り値に応じて異なります。
-
このメソッドが True を返す場合は、通常のページ・ログアウト動作が行われます。つまり、ページは再ロードされ、現在のセッションが終了済みの場合はログイン・ページが表示されます。
-
このメソッドが False を返す場合は、Zen はこのメソッドで指定された処理を実行してから、通常のページ・ログアウト動作を回避します。
ページのカスケーディング・スタイル・シート (.css) ファイルの名前をコンマで区切って並べたリスト。URL または単純なファイル名を使用できます。単純なファイル名を使用する場合は、該当するファイルへの物理パスを [CSPファイル物理パス] で指定します。詳細は、“Zen アプリケーションの構成” のセクションを参照してください。スタイル・シートの詳細は、"Zen の使用法" の “Zen のスタイル” の章を参照してください。
Zen のローカライズを使用する場合は、このパラメータの値を指定する必要があります。既定値は "" (ドメインを指定しない空文字列)。
Zen は、この文字列を、空白区切り属性のセットとして、出力ページの冒頭に生成された HTML タグに追加します。既定は、"" です (空文字列。何も追加されないことを示します)。
このページの JavaScript (.js) インクルード・ファイルの名前をコンマで区切って並べたリスト。URL または単純なファイル名を使用できます。単純なファイル名を使用する場合は、該当するファイルへの物理パスを [CSPファイル物理パス] で指定します。詳細は、“Zen アプリケーションの構成” のセクションを参照してください。
タイトルやラベルに使用可能なテキスト文字列を定義します。指定しない場合、Zen ページ・クラス名が使用されます。
<page> コンポーネントの title 属性の既定値。
現在のユーザが、このページを表示するため、またはクライアントからサーバ側メソッドを呼び出すためには、USE 特権を保持している必要があるシステム Resource の名前。
RESOURCE は、リソース名のコンマ区切りリストとすることもできます。この場合、ユーザはページを使用するために、指定された Resources の中の少なくとも 1 つで USE 特権を持つ必要があります。
詳細は、"Caché セキュリティ管理ガイド" の “アセットおよびリソース” の章にある “アプリケーション・リソース” を参照してください。
1 (True) の場合、ページの最後のコメントの中で、サーバの統計データ (ページ処理にかかった時間など) を表示します。0 (False) の場合、これは行われません。既定値は 1 です。
事前生成済みのインクルード・ファイルに記述された HTML クラスおよびスタイル定義を持つユーザ定義クラス・パッケージの名前をコンマで区切って並べたリスト。
事前生成済みのインクルード・ファイルに記述された SVG クラスおよびスタイル定義を持つユーザ定義クラス・パッケージの名前をコンマで区切って並べたリスト。
Zen の特殊変数
さまざまなタイプのインスタンス化したオブジェクトを Zen アプリケーションで表現するために、Zen には特殊変数がいくつか用意されています。このようなオブジェクトのメソッドとプロパティを Zen ページや Zen コンポーネント・クラスのコードから参照する際は、これらの変数が便利です。
サーバ側変数名 | 参照先 | 使用するクラス | Zen 実行時式での使用 |
---|---|---|---|
%application | アプリケーション・オブジェクト | ページ | なし |
%composite | 現在の複合オブジェクト (存在する場合) | ページ、コンポーネント | あり |
%page | 現在のページ・オブジェクト | ページ、コンポーネント | あり |
%query | 現在の ResultSet オブジェクト (存在する場合) | ページ、コンポーネント | あり |
%session | 現在の CSP セッション・オブジェクト | ページ、コンポーネント | あり |
%this | 現在のオブジェクト (ページまたはコンポーネント) | ページ、コンポーネント | あり |
%url | 現在のページの URI パラメータをプロパティとして持つオブジェクト。 | ページ、コンポーネント | あり |
%zenContext | サーバ・コードで現在実行している処理を示す文字列 | ページ | なし |
%url 特殊変数が値を持つのは、ページを初めて指定したときのみです。初めて指定した後のメソッド呼び出しやコンポーネントの更新で %url を参照しても、そのプロパティは値を持ちません。URI パラメータで渡された値を参照するには、使用するページ・クラスのプロパティを定義し、ZENURL パラメータを使用してそのプロパティを URI パラメータにリンクしたうえで、%page オブジェクトで目的の値を参照します。詳細は、“Zen ページの URI パラメータ” を参照してください。
一般的には、% 文字で始まるローカル変数名は、システムでのみ使用されます。アプリケーションで定義するローカル変数は、“%Z” または “%z” で開始できます。その他すべてのパーセントで始まる変数は、規則に従ってシステムで使用するために予約されています。この規則の詳細は、"Caché プログラミング入門ガイド" の “識別子のルールとガイドライン” を参照してください。
%application
サーバ側の %application 変数は、すべての Zen ページ・クラスで利用できます。これは、ページ・オブジェクトの作成中に実行するメソッドで使用することを目的としています。このページに関連付けられたアプリケーション・クラスの、サーバ上のインスタンスを参照します。これにより、そのアプリケーション・クラスで定義されているサーバ側メソッドをページから呼び出すことができます。
例えば、次のメソッドは SAMPLES ネームスペースのアプリケーション・クラス ZENDemo.ApplicationOpens in a new tab で定義されています。
ClassMethod GetQuickLinks(Output pLinks) As %Status
{
Set pLinks("Home") = "ZENDemo.Home.cls"
Set pLinks("Expense Calculator") = "ZENDemo.ExpenseCalculator.cls"
Set pLinks("MVC Master Detail") = "ZENMVC.MVCMasterDetail.cls"
Set pLinks("MVC Chart") = "ZENMVC.MVCChart.cls"
Set pLinks("MVC Meters") = "ZENMVC.MVCMeters.cls"
Set pLinks("MVC Form") = "ZENMVC.MVCForm.cls"
Set pLinks("Test Suite") = "ZENTest.HomePage.cls"
Set pLinks("Controls") = "ZENDemo.ControlTest.cls"
Set pLinks("Methods") = "ZENDemo.MethodTest.cls"
Quit $$$OK
}
このアプリケーションに関連付けられたページ・クラスは、このメソッドを次のように呼び出すことができます。
Class ZENDemo.ExpenseCalculator Extends %ZEN.Component.page
{
/// Application this page belongs to.
Parameter APPLICATION = "ZENDemo.Application";
// ...Intervening lines removed...
/// Return an array of quick links to be displayed by the locator bar.
ClassMethod GetQuickLinks(Output pLinks) As %Status
{
// dispatch to our application class
Quit %application.GetQuickLinks(.pLinks)
}
}
クライアント側には %application に相当する変数はありません。
%page および zenPage
Zen には、クライアント側およびサーバ側で Zen ページ・オブジェクトを表現するために、以下の特殊変数が用意されています。
-
サーバ側で実行する ObjectScript コード、Caché Basic コード、または Caché MVBasic コードでは、ページ・オブジェクトは次のように %page です。
Set btn = %page.%GetComponentById("NewBtn1")
-
Zen 実行時式では、ページ・オブジェクトは次のように %page です。
text id="rows" label="Rows:" value="#(%page.Rows)#" size="5"/>
-
クライアント側で実行する JavaScript メソッドでは、ページ・オブジェクトは次のように zenPage です。
var chart = zenPage.getComponentById('chart');
-
XML 属性の値である JavaScript 式では、ページ・オブジェクトは次のように zenPage です。
<button caption="+" onclick="zenPage.makeBigger();"/>
%this、this、および zenThis
Zen には、クライアント側およびサーバ側で Zen オブジェクト (コンポーネントまたはページ) を表現するための特殊変数が用意されています。
-
サーバ側で実行する ObjectScript コード、Caché Basic コード、または Caché MVBasic コードでは、次のようにオブジェクトそのものが %this です。
Set %this.Name = pSource.Name
-
Zen 実行時式では、次のようにオブジェクトそのものが %this です。
<html>Item #(%this.tuple)#: <b>#(%query.Title)#</b></html>
-
クライアント側で実行する JavaScript では、次のようにオブジェクトそのものが this です。
var out = this.getComponentById('events');
-
XML 属性の値である JavaScript 式では、次のようにオブジェクトそのものが zenThis です。
onchange="zenPage.changeLayout('svgFrame',zenThis.getValue());"
%zenContext
サーバで何らかの動作が Zen によって開始されるとき、それがどのようなタイプの動作であるかをサーバ側特殊変数 %zenContext で知ることができます。%zenContext は文字列です。%zenContext の値と、それに対応する動作は次のとおりです。
-
page:HTTP 要求に応えて Zen からページが提供されます。
-
submit:提出した要求が Zen で処理されます。
-
method:ハイパーイベントが Zen で処理されます。
コンパイル時に実行するコードで問題が発生することがあります。この問題を検出するには、以下を確認します。
$G(%zenContent)==""
クライアント側には %zenContext に相当する変数はありません。
クライアント側の関数、変数、およびオブジェクト
ここでは、Zen ページ・クラスで利用できる、クライアント側の JavaScript ユーティリティ関数、変数、およびオブジェクトについて説明します。
zen
zen(id)
id 値を使用して Zen コンポーネントを検索します。入力した id と一致するオブジェクトが返されます。
zen(id) JavaScript 関数は、ページ・オブジェクト上の以下のクライアント側 JavaScript メソッド呼び出しと同じ機能を持ちます。
zenPage.getComponentById(id)
次の例のように、JavaScript 構文が適切であれば、zen(id) 関数を使用できます。
<button caption="Save" onclick="zen('MyForm').save();"/>
zenEvent
zenEvent.property
次のような条件を想定します。
-
<listBox> などの Zen コンポーネント
-
onchange などのイベント・ハンドラ属性あり
-
値は JavaScript 式
-
ページ・クラスで定義されたクライアント側 JavaScript メソッドを呼び出す
-
次の <listBox> の例の notifyOnChange など
<listBox id="listBox" label="listBox" listWidth="240px"
onchange="zenPage.notifyOnChange(zenThis);"
value="2">
<option value="1" text="Apple" />
<option value="2" text="Banana" style="font-size: 1.5em; "/>
<option value="3" text="Cherry" />
</listBox>
notifyOnChange などのクライアント側 JavaScript メソッド内では、イベント自体 (マウスのクリックやキーの押下など) を表す JavaScript オブジェクトを参照できると便利です。このオブジェクトには、イベントの処理に使用できる補足情報が格納されます。そのために、zenEvent 特殊変数が用意されています。それぞれの zenEvent.type の値はテキスト文字列です。例えば、コードの中で以下のようにイベント・タイプをチェックできます。
if (zenEvent.type=="mousedown") {
// do something
}
以下の JavaScript の例では、グループ内で発生したマウス・クリックの正確な対象を特定する zenEvent.target 値を取得します。その目的は、クリックの対象が (エンクロージング <div> と zen 属性を持つ) グループ自身であるかグループ内のコンポーネントであるかを判断することです。
// look at source element; IE does not support standard target property.
var target = (null == zenEvent.target) ? zenEvent.srcElement : zenEvent.target;
// all enclosing divs will define an attribute called 'zen'.
var zen = target.getAttribute('zen');
if (zen) {
// do something
}
zenEvent オブジェクトは、DOM window.event データ構造と類似しています。 以下のプロパティは、zenEvent オブジェクトで使用できます。
-
zenEvent.clientX
-
zenEvent.clientY
-
zenEvent.returnValue
-
zenEvent.srcElement
-
zenEvent.target
-
zenEvent.type は、以下の値のいずれかを持つことができます。
W3C では、これらのイベントの種類、範囲、および処理について定義しています。ただし、この標準のサポートは、ブラウザごとに異なります。Firefox では、その実装内で全般的に遵守しています。 Internet Explorer はこの標準の一般的に使用されるサブセットを実装し、標準の中でサポートしていない多くの部分には代替機能を提供し、W3C 勧告以前から存在していたさまざまな独自のレガシー・イベントも引き続きサポートしています。クロスプラットフォームのサポートが必要な場合、その設計は以下のリストのイベントに限定する必要があります。
-
beforeunload
-
blur
-
change
-
click
-
contextmenu
-
dblclick
-
error
-
focus
-
keydown
-
keyup
-
keypress
-
load
-
mousedown
-
mouseup
-
mousemove
-
mouseout
-
mouseover
-
reset
-
resize *
-
select *
-
submit
-
unload
Note:このリストのアスタリスク (*) 付きのイベントの場合、その名前と意図はすべてのブラウザ間で標準的ですが、範囲、対象のコンテキスト、反映ルールはブラウザ固有になります。Safari では、ほとんどの標準イベントに加えて、いくつかのプラットフォーム固有の拡張機能が実装されています。一部のバージョンの Safari では、標準では dblclick は認識されません。
-
zenGetProp
zenGetProp(id,prop)
Zen コンポーネントの名前付きプロパティの値を返します。以下はその説明です。
-
id は、コンポーネントの ID でもコンポーネント・オブジェクト自体の ID でもかまいません。
-
prop は、設定するプロパティの名前です。
zenGetProp(id,prop) JavaScript 関数は、以下の ObjectScript メソッド呼び出しと同等です。
zenPage.getComponentById(id).getProperty(prop)
例えば、この JavaScript は以下のとおりです。
zenGetProp('ctrlButton','hidden');
これは、以下の ObjectScript と同等です。
zenPage.getComponentById('ctrlButton').getProperty('hidden');
zenIndex
zenIndex(idx)
システムによって割り当てられているコンポーネントのインデックス番号を使用して、Zen コンポーネントを検索します。繰り返しグループの中のコンポーネントの場合、ドットとその後に繰り返しグループの中のこのコンポーネントの位置を示す 1 ベースの番号を、インデックスに含めることができます。入力した idx と一致するオブジェクトが返されます。
この JavaScript 関数は、以下の ObjectScript メソッド呼び出しと同等です。
zenPage.getComponent( idx)
zenInvokeCallbackMethod
zenInvokeCallbackMethod(attr,ptr,'name',arg1,val1,arg2,val2,arg3,val3)
コールバック・メソッドを呼び出すためにコンポーネントで使用するユーティリティ関数。以下に zenInvokeCallbackMethod のすべての引数を示します。最初の 3 種類の引数は必須ですが、他の引数はオプションです。
-
コンポーネント・オブジェクトのコールバック属性。this.onclick、this.onchange などがあります。この属性の値は、クライアント側 JavaScript メソッドを呼び出す JavaScript 式とする必要があります。
-
コンポーネント・オブジェクトを指すポインタ。this などがあります。
-
イベントの HTML 名 (引用符で囲んで表記します)。
-
オプションで指定する 4 番目の引数は、コールバック・メソッドに渡す仮パラメータの名前です。
-
4 番目の引数を指定した場合、5 番目の引数には仮パラメータの値を指定します。
-
zenInvokeCallbackMethod では、引数の名前と値の組み合わせを、上記のほかに最大 2 つ指定できます。これらは、zenInvokeCallbackMethod の 6 ~ 9 番目の引数として指定します。
次に例を示します。
zenInvokeCallbackMethod(this.onclick,this,'onclick')
この例の詳細は、“カスタム・コンポーネント” の章の “HTML 要素へのイベント・ハンドラのアタッチ” を参照してください。
zenLaunchPopupWindow
非推奨。代わりに、Zen ページ・メソッド launchPopupWindow を呼び出すクライアント側メソッドを使用します。詳細は、"Zen コンポーネントの使用法" の “ポップアップ・ウィンドウとダイアログ” の章にある “ポップアップ・ウィンドウ” を参照してください。
zenLink
zenLink(uri)
URI としての使用を意図した文字列にある特殊文字をすべてエスケープする関数。uri は、有効な文字列である必要があります。以下のように、一重引用符でリテラル文字列を囲みます。
zenLink('MyApp.MyDialog.cls')
"Zen コンポーネントの使用法" の “ポップアップ・ウィンドウとダイアログ” の章にある “ポップアップ・ウィンドウ” も参照してください。
zenPage
zenPage.property
zenPage.method(parameters)
zenPage は、クライアント側の %page に相当するものです。“Zen の特殊変数” の “%page および zenPage” を参照してください。
zenSetProp
zenSetProp(id,prop,value)
Zen コンポーネントの名前付きプロパティの値を設定します。以下はその説明です。
-
id は、コンポーネントの ID でもコンポーネント・オブジェクト自体の ID でもかまいません。
-
prop は、設定するプロパティの名前です。
-
value は、プロパティに割り当てる値です。
zenSetProp(id,prop,value) JavaScript 関数は、以下の ObjectScript メソッド呼び出しと同等です。
zenPage.getComponentById(id).setProperty(prop,value)
例えば、この JavaScript は以下のとおりです。
zenSetProp('ctrlButton','hidden', false);
これは、以下の ObjectScript と同等です。
zenPage.getComponentById('ctrlButton').setProperty('hidden',false);
zenSynchronousMode
zenSynchronousMode
True または False の値を持つフラグ。True の場合、すべてのメソッドは、返り値を持つかどうかに関係なく、同期的に実行されます。False の場合、返り値を持つメソッドは同期的に実行され、返り値を持たないメソッドは非同期で実行されます。“同期メソッドと非同期メソッド.” を参照してください。
zenText
zenText(id,p1,p2,p3,p4)
zenText は、クライアント側の $$$Text に相当するものです。“Zen のローカライズ” の章の “クライアント側のテキストのローカライズ” を参照してください。
zenThis
zenThis.property
zenThis.method(parameters)
zenThis は、クライアント側の %this に相当するものです。“Zen の特殊変数” の “%this、this、および zenThis” を参照してください。
Zen 実行時式
クライアントで実行するページでは、Zen ページの記述で必ず静的情報を指定するのではなく、サーバで実行する実行時式を呼び出せるようにしたほうが便利なことがあります。例えば、ボタンのキャプション・テキストを、現在ログインしているユーザの ID に応じて実行時にサーバ側でのみ判断できる内容に変更する必要がある場合です。この内容は、実行時のさまざまな値によって決まります。この理由から、Zen には、実行時にサーバのみで解決できる式をクライアント側アプリケーションのコードに記述する方法が用意されています。
Zen 実行時式の構文規則は独特です。
実行時式は #()# の中に記述し、例えば次のようにします。
<button caption="#(myObject.myProperty)#" />
myProperty には、実行時にサーバで具体的な値が割り当てられます。
Zen 実行時式の構文は、次のような状況でのみ、制限付きで使用できます。
-
XData ブロックに埋め込んだ XML (XML の特定の要素および属性のみ)
-
ZenMethod の &js<> ブロックに埋め込んだ JavaScript
-
onclick など、XML 属性の値として指定した JavaScript 式
-
サーバ側メソッドの &html<> ブロックに埋め込んだ HTML
次の項目は、Zen 実行時式の区切り文字 #()# の中には記述できません。
-
%this.method() などのメソッド。プロパティのみが許可されます。
-
最初のレベルより大きいレベルのプロパティ。例えば、this.parent.other.thing. などのチェーンは許可されません。
-
$$$Text などのマクロの呼び出し。
-
JavaScript 式。
-
ObjectScript 式。サーバ側の ObjectScript または ZenMethod の中に記述する実行時式は、この規則の例外です。“サーバ側メソッドに記述する実行時式” を参照してください。
XML に記述する実行時式
Zen クラスの XData ブロックで Zen 実行時式を使用できますが、特定の XML 要素および XML 属性の値にのみ、Zen 実行時式を記述できます。この例として、<button> の caption 属性があります。
<button caption="#(%query.Name)#" onclick="alert('#(%query.Name)#')"/>
<button> が持つすべての属性のうち、Zen 実行時式をサポートしているのは caption、value、および hidden のみです。前述の例にある onclick の値には Zen 実行時式が記述されていますが、これが可能な理由は、onclick の値が、#()# 構文を記述できる JavaScript 式であるからです。前述のトピックにある制限の一覧を参照してください。
このドキュメントでは、Zen 実行時式をサポートする XML 要素と XML 属性をわかりやすく識別できるようになっています。このドキュメントのテキストで #()# 文字列を検索すると、これらを探し出すことができます。
XML 属性が実行時式をサポートしているかどうかを知る別の方法として、対応するプロパティでデータ型のパラメータ ZENEXPRESSION が 1 (True) に設定されているかどうかを Caché クラスのドキュメントで調べる方法があります。
プロパティで ZENEXPRESSION=1 を設定して実行時式をサポートすることはできません。組み込みの Zen コンポーネント・クラスで ZENEXPRESSION=1 を設定しているのは、そのプロパティが実行時式をサポートしていることを示すためであって、サポートできるようにするためではありません。
一方、独自にコンポーネントのサブクラスを作成する場合は、そのサブクラスのプロパティで ZENEXPRESSION=1 を設定できます。このプロパティはカスタム・コンポーネント・クラスのものであることが必要です。組み込み Zen コンポーネント・クラスのプロパティでは設定できません。詳細は、“カスタム・コンポーネント” の章の “データ型のパラメータ” を参照してください。
Zen 実行時式をサポートする XML 属性は数多く存在しますが、同様のサポートを提供する XML要素は 1 つのみです。その要素は <html> コンポーネントです。この要素には、リテラル・テキストと #()# 実行時式を記述できます。以下はその例です。
<html>Item #(%this.tuple)#: <b>#(%query.Title)#</b></html>
実行時式と特殊変数
実行時式では、“Zen の特殊変数” で説明したサーバ側特殊変数を使用できます。Zen 実行時式では、次のサーバ側特殊変数のみをサポートしています。
-
%composite
-
%page
-
%query
-
%session
-
%this
-
%url
ページの開発者は、事前定義したオブジェクトのプロパティ値のみに式を制限することで、クライアントで表示できるサーバ側の値を制御できます。このような制限を設けないと、ページの開発者が意図しないコードがページで実行される可能性があり、その結果、セキュリティ上のリスクが発生します。
例えば、Zen の式に使用されている %session は、サーバ側の %session オブジェクトではありません。%session オブジェクトからユーザ・データの値を得るための評価が可能なのは、クライアント側の式です。値が test である id を持つコンポーネントがページにあるとします。Zen の式に次の記述があるとします。
#(%session.test)#
サーバでは、この式が次のようになります。
%session.Data("test")
この結果、値が test である id を持つコンポーネントに関連付けられた値が、Zen の式に返されます。
%session オブジェクトの詳細は、ドキュメント "Caché Server Pages (CSP) の使用法" の “%CSP.Session オブジェクト” を参照してください。
サーバ側メソッドに記述する実行時式
&html<> ブロックを持つサーバ側メソッドの例を以下に示します。この例では、実行時式で ObjectScript 関数 $ZCONVERT ($ZCVT) を呼び出し、箇条書きリストの要素を書き出せるようにします。
Method %DrawHTML()
{
&html<<div class="demoSidebar">>
Write $ZCVT(..text,"O","HTML")
#; bullets
Set tCount = ..bullets.Count()
If (tCount > 0) {
&html<<ul>>
For n = 1:1:tCount {
Set tBullet = ..bullets.GetAt(n)
&html<<li>#($ZCVT(tBullet.text,"O","HTML"))#</li>>
}
&html<</ul>>
}
}
&js<> ブロックを持つ ZenMethod の例を以下に示します。この例では、実行時式でサーバ側の識別子 pIndex を、クライアントでの実行が必要な JavaScript コードに渡します。この例にある 2 番目の &js<> ブロックでは、実行時式で ObjectScript 関数 $RANDOM ($R) を呼び出して描画位置の座標を生成し、グラフィカル・オブジェクトを構成する CSS スタイル文を作成しています。
ClassMethod GetSVGContents(pIndex As %Integer) [ ZenMethod ]
{
#; get the svg component
&js<var svg = zenPage.getComponent(#(pIndex)#);>
#; lines
For i=1:1:30 {
&js<
var line = svg.document.createElementNS(SVGNS,'circle');
//line.setAttribute('x1',200);
//line.setAttribute('y1',100);
line.setAttribute('r',5);
line.setAttribute('cx',#(10+$Random(380))#);
line.setAttribute('cy',#(10+$Random(180))#);
line.setAttribute('style',
'#("fill: yellow; stroke: black; stroke-width: 2;")#');
svg.svgGroup.appendChild(line);
>
}
Quit
}
ここで紹介したサンプルは、サーバ側メソッドで実行時式をどのように使用できるかを示しています。クライアント側の JavaScript メソッドでは、実行時式を使用せずに同様の結果を得ることができます。
Zen プロキシ・オブジェクト
クライアント・ページとサーバ・プロセス間で任意のデータを受け渡しする簡単な方法があると便利です。このため、Zen ではプロキシ・オブジェクトと呼ばれる、シンプルな汎用オブジェクトを定義します。以下を実行できます。
-
サーバに引き渡す (サーバ・オブジェクトとして自動的に配列されます)
ここでは、この順序を説明し、構文の例を示します。
クライアントのプロキシ・オブジェクト
クライアントでは、プロキシ・オブジェクトは JavaScript の zenProxy オブジェクトのインスタンスにすぎません。他のオブジェクトと同様に、zenProxy オブジェクトを作成して、このプロパティにデータを入力できます。例えば以下のようになります。
var proxy = new zenProxy();
proxy.Name = 'John Smith';
proxy.City = 'Boston';
プロパティの設定
プロキシ・オブジェクトは完全に汎用で、事前定義されたプロパティはありません。zenProxy オブジェクトには任意のプロパティ値を設定できますが、以下のような制約を受けます。
-
プロパティの値は、リテラル値 (文字列または数字) であり、オブジェクトや関数であってはなりません。リテラル値のみがサポートされるため、zenProxy プロパティの値がオブジェクトになるように設定することはできません。このような、より複雑なオブジェクトが必要な場合は、通常の Zen オブジェクトを作成してください。
-
プロパティの名前が JavaScript 内で有効であることが必要です。
-
zenProxy オブジェクトは、Zen コンポーネントのプロパティではありません。Zen コンポーネント・クラスで以下のような構文を使用すると、コンパイルは失敗します。
Property a As %ZEN.proxyObject;
代わりに、サブクラス %ZEN.Component.objectOpens in a new tab を使用します。
プロパティの削除
Clear メソッドを使用して、zenProxy オブジェクト内のすべてのプロパティを削除できます。
obj.clear();
サーバへのプロキシ・オブジェクトの受け渡し
ZenMethod を定義して、引数の 1 つに %ZEN.proxyObjectOpens in a new tab タイプを宣言することで、プロキシ・オブジェクトをサーバに渡すことができます。以下はその例です。
ClassMethod MyMethod(pProxy As %ZEN.proxyObject) As %Boolean [ZenMethod]
{
Set x = pProxy.Name
Quit 1
}
サーバのプロキシ・オブジェクト
クライアントが MyMethod を呼び出すと、(前述のトピックで定義されているとおり) zenProxy オブジェクトのインスタンスがサーバに渡されます。サーバでは、このインスタンスは、クライアント・オブジェクトと同じプロパティをすべて持つ %ZEN.proxyObjectOpens in a new tab に自動的に変換されます。
また、サーバ側の %ZEN.proxyObjectOpens in a new tab オブジェクトも完全に汎用で、事前定義されたプロパティはありません。
%ZEN.proxyObjectOpens in a new tab のインスタンスに、$Data 関数または $Get 関数を使用してはいけません。これを行うと、関数から "無効なプロパティ" エラーが返されます。
プロパティの取得
通常のプロパティ構文を使用して、%ZEN.proxyObjectOpens in a new tab から値を取得できます。以下はその例です。
Set a = pProxy.property1
Set b = pProxy.property2
%CopyToArray メソッドを使用すると、ローカル配列として、%ZEN.proxyObjectOpens in a new tab オブジェクト内の一連のプロパティを取得することもできます。
Do pProxy.%CopyToArray(.array)
現在定義されていないプロパティを参照する場合は、エラーではない "" の値を取得します。
プロパティの設定
プロパティを設定すると、プロパティが既に定義されていない場合は自動的に定義されます。
Set pProxy.property3 = "value"
%ZEN.proxyObjectOpens in a new tab オブジェクト内の一連のプロパティを設定する %CopyFromArray メソッドもあります。
プロパティの削除
%Clear メソッドを使用すると、サーバ側の %ZEN.proxyObjectOpens in a new tab オブジェクトからすべてのプロパティを削除できます。
Do pProxy.%Clear()
クライアントへの値の受け渡し
%ZEN.proxyObjectOpens in a new tab オブジェクトを受け取る ZenMethod がそのオブジェクトを変更すると、メソッド呼び出しが完了したときに、変更内容が自動的にオブジェクトのクライアント・バージョンに適用されます。これは追加または削除されたすべてのプロパティが含まれます。
ZenMethod が値を返さない場合は、後で非同期で実行されます。これは Zen の通常の動作です。詳細は、“同期メソッドと非同期メソッド” のセクションを参照してください。この場合、クライアント側の zenProxy オブジェクトに加えた変更は引き続き適用されますが、これらの変更が適用されるタイミングはわかりません。
%ZEN.proxyObjectOpens in a new tab を返す ZenMethod を定義することもできます。
ClassMethod MyCreate() As %ZEN.proxyObject [ZenMethod]
{
Set tProxy = ##class(%ZEN.proxyObject).%New()
Set tProxy.Data = "Some data from the server"
Quit tProxy
}
クライアント・メソッドは、以下のように、この ZenMethod を呼び出すことができます。
ClientMethod clientMethod() [Language = JavaScript]
{
var proxy = zenPage.MyCreate();
alert(proxy.Data);
}
プロキシ・オブジェクトの例
このセクションでは、プロキシ・オブジェクトを使用できるようにする組み込みの Zen コンポーネントについて説明します。
<html>
<html> コンポーネントでは、コンポーネントのコンテンツを指定できる OnDrawContent コールバックが提供されます。このコールバックは、コールバック・メソッドによって解釈されるアプリケーション固有の文字列である seed 値を受け取ります。クライアントがこの seed 値を zenProxy オブジェクトに設定すると、OnDrawContent コールバックが呼び出されたときに、サーバの %ZEN.proxyObject として自動的に配列されます。
Zen ページで <html> コンポーネントを以下のように定義するとします。
<html id="html" OnDrawContent="DrawHTML"></html>
また、OnDrawContent も以下のように定義します。この OnDrawContent メソッドは、入力引数 pSeed がオブジェクトかどうかを確認し、オブジェクトである場合は、Name プロパティと SSN プロパティを取得して表示します。それ以外の場合はエラー・メッセージを表示します。
ClassMethod DrawHTML(pSeed As %String) As %Status
{
If $IsObject(pSeed) {
&html<<table>>
&html<<tr><td>Name:</td><td>#(pSeed.Name)#</td></tr>>
&html<<tr><td>SSN:</td><td>#(pSeed.SSN)#</td></tr>>
&html<</table>>
}
Else {
&html<<i>No data to display</i>>
}
Quit $$$OK
}
新しい zenProxy オブジェクトをインスタンス化すると、この <html> コンポーネントをクライアント側の JavaScript メソッドから更新できます。値をそのオブジェクトの Name プロパティと SSN プロパティに割り当て、この zenProxy オブジェクトを <html> コンポーネントの seed プロパティの値として割り当てた後、以下の JavaScript の例のように、コンポーネントを更新します。
ClientMethod updateHTML() [Language = JavaScript]
{
// find the html component
var html = zen('html');
if (html) {
var proxy = new zenProxy();
proxy.Name = 'John';
proxy.SSN = '222-22-2222';
// set seed value and invoke server refresh
html.setProperty('seed',proxy);
html.refreshContents();
}
}
<html> コンポーネントの詳細は、"Zen コンポーネントの使用法" の “その他の Zen コンポーネント” の章を参照してください。
<dataController>
<dataController> コンポーネントには、<dataController> 内の現在のプロパティ・セットを zenProxy オブジェクトとして返す getDataAsObject() メソッドがあります。これにより、<dataController> に既に組み込まれている場合以外でも、コントローラからのデータの取得およびサーバへの受け渡しが容易になります。
<dataController> コンポーネントの詳細は、"Zen コンポーネントの使用法" の “モデル・ビュー・コントローラ” の章の “データ・コントローラ” のセクションを参照してください。
<form> および <dynaForm>
<form> コンポーネントと <dynaForm> コンポーネントには、このフォーム内のすべてのコントロールの現行値を zenProxy オブジェクトとして返す getValuesAsObject() メソッドがあります。このプロキシ・オブジェクト内のプロパティの名前は、各コントロールの name 属性に基づいています。
<form> コンポーネントと <dynaForm> コンポーネントの詳細は、"Zen コンポーネントの使用法" の “Zen のフォーム” の章を参照してください。
Zen の JSON コンポーネント
Zen の <altJSONProvider> コンポーネントを使用すると、クライアントとサーバの間で JavaScript Object Notation (JSON) 形式を使用してオブジェクト・データの伝送ができるようになります。Zen は、<altJSONProvider> の特別なバージョンも提供します。これについては、“altJSONSQLProvider” のサブセクションで説明しています。
Zen コンポーネントの <altJSONSQLProvider> は、<jsonSQLProvider> に代わるコンポーネントです。後者については、今後は詳しく説明しません。<altJSONProvider> コンポーネントは、パフォーマンスに優れ、<jsonProvider> コンポーネントと同じ方法で使用できます。同様に、<altJSONSQLProvider> によって <jsonSQLProvider> が置き換えられます。
概要
JSON とは、オブジェクト・リテラル構文を使用して 1 つ以上のオブジェクトから成るセットの定義を可能にする JavaScript プログラミング技法です。次に例を示します。
var obj = {name:'Bill', home:'New York'};
Zen の <altJSONProvider> コンポーネントは以下のように機能します。
-
非表示の <altJSONProvider> コンポーネントのインスタンスを、XData Contents 内の <page> 定義内に配置します。
-
<altJSONProvider> の OnGetTargetObject 属性の値を指定します。この属性は、オブジェクトまたはオブジェクト・セットを作成して返すページ・クラス内のメソッドの名前です。返されたオブジェクトは、特定のクラスまたはクラス群のインスタンスになることも、Zen プロキシ・オブジェクト・クラスである %ZEN.proxyObjectOpens in a new tab を使用することもできます。
-
OnGetTargetObject コールバック・メソッドを記述します。“OnGetTargetObject コールバック・メソッド” を参照してください。
-
ページがレンダリングされると、<altJSONProvider> はターゲット・オブジェクトを一連の JavaScript オブジェクトに変換します。クライアントに送信されるページのソースを表示している場合は、これらのオブジェクトを参照できます。
-
<altJSONProvider> には、ターゲット・オブジェクトのクライアント側バージョンを返すクライアント側メソッド getContentObject() があります。これは、ターゲット・オブジェクトと同じプロパティと値を持つ汎用 JavaScript オブジェクトのグラフです。ターゲット・オブジェクトが他のオブジェクトを参照しているか、コレクション (リテラル値またはオブジェクト値を使用) を持っている場合は、JavaScript オブジェクトは対応するオブジェクトまたはコレクションのプロパティを持ちます。クライアントは、これらのクライアント側オブジェクトを変更することも、getContentObject() メソッドを使用してこれらのオブジェクトを完全に置換することもできます。
-
クライアントは、submitContent() メソッドを呼び出して、そのコンテンツ・オブジェクトを処理するためにサーバに返送できます。これにより、これらのオブジェクトが元のサーバ側オブジェクトに変換されて、<altJSONProvider> の OnSubmitContent プロパティで指定されたページ・クラス・メソッドが呼び出されます (存在する場合)。
-
OnSubmitContent を使用している場合は、ページ・クラス内で対応するメソッドを記述します (下記の詳細を参照)。OnSubmitContent コールバック・メソッドは、このメソッドに渡されたオブジェクトを変更することも、まったく異なるオブジェクト・セットを返すこともできます。これにより、<altJSONProvider> を使用して各種のサーバ操作を実行することが可能になります。
-
XData Contents 内の <altJSONProvider> 要素に対して選択する属性に応じて、および Zen ページ・クラス内で記述するコールバック・メソッドの内容に応じて、代替のアクションを使用できます。
<altJSONProvider> コンポーネントをオブジェクト・トランスポートとして使用することには、Zen で提供されている他のメカニズム (Zen コンポーネント用に提供されている組み込みトランスポートなど) と比較すると、利点と欠点があります。主な利点は、サーバ・クラスを作成も変更もすることなくデータを伝送できることです。この技法を使用すると、ほとんどすべてのサーバ側オブジェクトを伝送できます。欠点は以下のとおりです。
-
オブジェクトのセットを伝送できますが、これらのオブジェクトは親オブジェクトから子レベルにいたるまでのグラフを形成している必要があります。この要件は、JSON フォーマット・データがクライアント上で再構築される方法に起因します。子オブジェクトから親オブジェクト、兄弟オブジェクト、またはこのグラフ外の他のオブジェクトを参照させることはできません。
-
この手法は遅延バインディングを使用するため、Zen コンポーネントで使用されるコード生成手法より効率性は劣ります。
-
すべてのオブジェクト・プロパティがサポートされるわけではありません。ストリームやバイナリ値は伝送できません。子オブジェクトへの参照のみが伝送されます。
<altJSONProvider> 要素には、ゼロ個以上の <parameter> 要素を記述できます。それぞれの <parameter> は引数として、OnGetTargetObject、OnGetArray、または OnRenderJSON という属性のうち、JSON フォーマット・オブジェクトを生成するために使用されている属性で指定されたコールバック・メソッドに渡されます。これらの <altJSONProvider> 属性は相互に排他的であるため、<altJSONProvider> で指定された <parameter> 値は、OnGetTargetObject、OnGetArray、または OnRenderJSON という属性のうち 1 つのみで実際に使用されます。
<parameter> 要素には以下の属性があります。
属性 | 説明 |
---|---|
paramName | paramName は <altJSONProvider> 内で一意であることが必要です。コールバック・メソッドに渡されるパラメータの配列の添え字となります。 |
value | <parameter> に指定する value には、リテラル文字列のほか、Zen #()# 実行時式も使用できます。 |
“OnGetTargetObject コールバック・メソッド” セクションに、<parameter> を使用した例を示しています。この構文は、他のコールバックについても同じです。Zen コンポーネントでの <parameter> 要素の使用例は、"Zen コンポーネントの使用法" の “Zen のテーブル” という章の “データ・ソース” および “クエリ・パラメータ” を参照してください。
JSON Provider のプロパティ
XData Contents 内の XML 要素として、<altJSONProvider> には次のテーブルに示す属性があります。
属性 | 説明 |
---|---|
OnGetArray |
ページ・クラス内で定義されているコールバック・メソッドの名前。このメソッドは、この <altJSONProvider> 要素が含まれたページがレンダリングされるときに自動的に呼び出されます。“OnGetArray コールバック・メソッド” を参照してください。 |
OnGetTargetObject |
ページ・クラス内で定義されているコールバック・メソッドの名前。このメソッドは、この <altJSONProvider> 要素が含まれたページがレンダリングされるときに自動的に呼び出されます。“OnGetTargetObject コールバック・メソッド” を参照してください。 |
OnRenderJSON |
ページ・クラス内で定義されているコールバック・メソッドの名前。このメソッドは、この <altJSONProvider> 要素が含まれたページがレンダリングされるときに自動的に呼び出されます。 “OnRenderJSON コールバック・メソッド” を参照してください。 |
OnSubmitContent |
ページ・クラス内で定義されているコールバック・メソッドの名前。このメソッドは、クライアントが submitContent() というクライアント側メソッドを呼び出してオブジェクトをサーバに送信するときに呼び出されます。“OnSubmitContent コールバック・メソッド” を参照してください。 |
targetClass |
この <altJSONProvider> コンポーネントによって提供されること想定しているターゲット・オブジェクトのクラス名。 %SetTargetObject(obj) メソッドを呼び出すことで、targetClass の値をサーバ側コードから動的に設定できます。obj には %RegisteredObject へのポインタを指定します。 |
これらの属性のいくつかは、次のように相互にオーバーライドします。
-
OnGetTargetObject コールバック・メソッドはオブジェクトのビューを提供します。
-
OnGetArray コールバックが定義されている場合は、ページでは、OnGetTargetObject コールバックの代わりに OnGetArray コールバックが呼び出されてビューが取得されます。
-
OnRenderJSON コールバックが定義されている場合は、OnRenderJSON コールバック内の処理は、<altJSONProvider> コンポーネントのレンダリング時の既定動作をすべてオーバーライドします。したがって、OnGetTargetObject や OnGetArray で指定されているコールバックは呼び出されません。OnRenderJSON コールバックはすべての処理を単独で実行します。
OnGetArray コールバック・メソッド
OnGetArray プロパティで指定されたメソッドを使用すると、多次元配列の内容を入力することで一連の同一オブジェクトをクライアントに簡単に伝送できます。
以下の例は、OnGetArray で指定されたメソッドの必要なシグニチャを示しています。
Method GetArray(ByRef pParameters,
Output pMetaData,
Output pData) As %Status
{
Set pMetaData = $LB("name","rank","serialNo")
Set pData(1) = $LB("Smith","Captain","444-33-2222")
Set pData(2) = $LB("Jones","Corporal","333-22-3333")
Quit $$$OK
}
以下はその説明です。
-
pParameters は、paramName を添え字とする <parameter> 値の配列です。<parameter> 値は、<altJSONProvider> の定義内ではオプションです。これらの値は、コールバック・メソッドで必要な場合にのみ指定する必要があります。<parameter> の例は、OnGetTargetObject を参照してください。
-
pMetaData は、オブジェクトのプロパティの名前がその登場順に格納されている $List です。このメソッドによってこの構造体の内容を入力する必要があります。
-
pData はデータが格納されている配列です。この配列内の各ノードは、プロパティの値が格納された $List である必要があります。これは、pMetaData で提供されるメタデータと一致する必要があります。このデータ配列では、任意の添え字値を使用できます。階層配列を定義することも可能です。この場合は、子ノードは children という親コレクション内に配置されます。このメソッドによってこの構造体の内容を入力する必要があります。
上記のケースでは、<altJSONProvider> の定義によって以下が指定されます。
<altJSONProvider OnGetArray="GetArray" />
上記の例では、次のように 2 つのオブジェクトが JSON フォーマットでクライアントに伝送されます。
var content = {
name:'Smith',rank:'Captain',serialNo:'444-33-2222',
children:[
{
name:'Jones',rank:'Corporal',serialNo:'333-22-3333'
}
]
};
OnGetTargetObject コールバック・メソッド
以下の例は、OnGetTargetObject で指定されたメソッドの必要なシグニチャを示しています。
Method GetTarget(ByRef pParameters,
Output pObject As %RegisteredObject) As %Status
{
Set pObject = ##class(MyApp.MyClass).%New()
Set pObject.Name = "Bob"
Set pObject.Department = pParameters("Dept")
Quit $$$OK
}
以下はその説明です。
-
pParameters は、paramName を添え字とする <parameter> 値の配列です。<parameter> 値は、<altJSONProvider> の定義内ではオプションです。 これらの値は、コールバック・メソッドで必要な場合にのみ指定する必要があります。
-
pObject は、JSON フォーマットでクライアントに渡されるデータが含まれたオブジェクトのインスタンスです。このメソッドは、このオブジェクトを参照によって返す必要があります。pObject は、このトピックで説明している JSON の制限事項を満たす任意のオブジェクトです。実際には、pObject は、“Zen プロキシ・オブジェクト” で説明されている Zen プロキシ・オブジェクトでもかまいません。
この方法で永続オブジェクトをデータベースから直接伝送することは推奨されません。特に、そのオブジェクトに他のオブジェクトへの参照が含まれている場合は避ける必要があります。そうしないと、最終的にデータベース全体がクライアントに伝送されてしまう可能性があります。このようなケースでは、よりシンプルなラッパ・オブジェクトを使用することをお勧めします。
上記のケースでは、<altJSONProvider> の定義によって以下が指定されます。
<altJSONProvider OnGetTargetObject="GetTarget" >
<parameter paramName="Dept" value="Sales" />
</altJSONProvider>
OnRenderJSON コールバック・メソッド
これは、非常に特殊な状況向けの高度なコールバックです。このメソッドを使用すると、クライアントに対してレンダリングしようとしている正確な JSON コンテンツを書き出すことができます。この機能を使用するには、JavaScript のデバッグに精通している必要があります。
以下の例は、OnRenderJSON で指定されたメソッドの必要なシグニチャを示しています。
Method RenderHandler(ByRef pParameters) As %Status
{
/// Render activities here
Quit tSC
}
以下はその説明です。
-
pParameters は、paramName を添え字とする <parameter> 値の配列です。<parameter> 値は、<altJSONProvider> の定義内ではオプションです。 これらの値は、コールバック・メソッドで必要な場合にのみ指定する必要があります。 <parameter> の例は、OnGetTargetObject を参照してください。
上記のケースでは、<altJSONProvider> の定義によって以下が指定されます。
<altJSONProvider OnRenderJSON="RenderHandler" />
OnSubmitContent コールバック・メソッド
以下の例は、OnSubmitContent で指定されたメソッドの必要なシグニチャを示しています。
Method SubmitHandler(pCommand As %String,
pProvider As %ZEN.Auxiliary.altJSONProvider,
pObject As %RegisteredObject,
Output pResponse As %RegisteredObject) As %Status
{
Set tSC = $$$OK
If ($IsObject(pObject)) {
Set tSC = pObject.%Save()
}
Quit tSC
}
以下はその説明です。
-
pCommand は、submitContent() に渡されるコマンド文字列です。
-
pProvider は、JSON プロバイダ・オブジェクトです。
-
pObject は、JSON フォーマットから元のオブジェクト・インスタンスに変換された後の送信済みオブジェクトです。
-
このコールバック・メソッドが pResponse 引数を介してオブジェクトを返す場合は、このオブジェクトはクライアントに返されて、JSON プロバイダの新しいコンテンツとなります。
このケースでは、<altJSONProvider> の定義によって以下が指定されます。
<altJSONProvider OnSubmitContent="SubmitHandler" />
JSON Provider のメソッド
<altJSONProvider> 要素は、%ZEN.Auxiliary.altJSONProviderOpens in a new tab クラスの XML プロジェクションです。このクラスのオブジェクトは、クライアント側のコンポーネントを操作するために呼び出すことができるいくつかのメソッドを提供します。以下のテーブルではこれらのメソッドについて説明しています。
クライアント側メソッド | 説明 |
---|---|
getContentObject() | クライアント側の JSON データをオブジェクトとして返します。JSON データがない場合は、NULL を返します。 |
getError() | サーバ側で発生したエラーの現行値を取得します。詳細は、submitContent() を参照してください。 |
reloadContents() |
サーバから提供されるデータを使用して JSON プロバイダのコンテンツを再ロードします。submitContent() メソッドとは異なり、reloadContents() はサーバにデータを送信しません。 reloadContents() は、一般に OnGetArray コールバックと組み合わせて使用されます。reloadContents() はサーバを呼び出し、次にサーバは OnGetArray コールバックを呼び出して、クライアントに返送する新しいコンテンツを作成します。 |
setContentObject(obj) | obj をこの JSON プロバイダの新しいターゲット・オブジェクトに設定します。 |
setContentText(json) | json 引数で指定された文字列を使用して、このプロバイダのコンテンツを設定します。json は、JSON フォーマットのオブジェクト・データを格納している必要があります。 |
submitContent(cmd,target) |
このプロバイダの現在のターゲット・オブジェクトを処理するためにサーバに送信します。これにより、このオブジェクトがサーバ上で再作成されて、OnSubmitContent コールバック・メソッドが呼び出されます。 submitContent() には以下の引数があります。
submitContent() メソッドは、正常に実行された場合は True を返し、そうでない場合は False を返します。このメソッドをサーバ上で正常に実行できなかった場合は、そのエラーを説明する文字列が記録されます。この文字列は、getError() メソッドを使用してクライアント側で取得できます。 |
altJSONSQLProvider
Zen の <altJSONSQLProvider> コンポーネントは、具体的に説明されなくなった <jsonSQLProvider> コンポーネントに代わるコンポーネントです。<altJSONSQLProvider> コンポーネントは、パフォーマンスに優れ、<jsonSQLProvider> コンポーネントと同じ方法で使用できます。
<altJSONSQLProvider> コンポーネントは、SQL 文を使用してクライアントにデータを供給します。以下の方法で SQL 文を指定できます。
-
sql 属性の値として指定
-
OnGetSQL コールバック・メソッド内で指定
-
queryClass および queryName 属性を指定することによってクラス・クエリとして指定
以下のコード・フラグメントは、sql 属性の使用法を示しています。
<page xmlns="http://www.intersystems.com/zen">
<altJSONSQLProvider id="json"
sql="SELECT ID,Name,SSN,DOB FROM Sample.Person" />
<dataGrid id="grid" controllerId="json"/>
</page>
次の例に示すように SQL 文にパラメータを指定することもできます。
<page xmlns="http://www.intersystems.com/zen">
<altJSONSQLProvider id="jsonSQL"
sql="SELECT ID,Name,Age FROM Sample.Person where Name %STARTSWITH ? or Age ?" >
<parameter paramName="1" value="Z"/>
<parameter paramName="2" value="80"/>
</altJSONSQLProvider>
<dataGrid id="grid" controllerId="jsonSQL"/>
</page>
次のコード・フラグメントは、<altJSONSQLProvider> の OnGetSQL 属性を設定し、イベント・ハンドラに渡されるパラメータを指定します。
<page xmlns="http://www.intersystems.com/zen">
<altJSONSQLProvider id="jsonSQL" OnGetSQL="GetSQL" >
<parameter paramName="1" value="Z"/>
<parameter paramName="2" value="80"/>
</altJSONSQLProvider>
<dataGrid id="grid" controllerId="jsonSQL"/>
</page>
このコード・サンプルは、OnGetSQL コールバック・メソッドの実装を示しています。ここでは <altJSONSQLProvider> に指定されるパラメータを使用します。
Method GetSQL(ByRef pParm As %String,
ByRef pSQL As %String,
pCriteria As %ZEN.proxyObject,
ByRef pPagingInfo As %String) As %Status
{
Set pSQL = "SELECT ID,Name,Age FROM Sample.Person where Name %STARTSWITH ? or Age > ?"
Quit $$$OK
}
次の例では、クラス・クエリを使用して SQL 文を指定します。
<page xmlns="http://www.intersystems.com/zen">
<altJSONSQLProvider id="jsonSQL"
queryClass="Sample.Person" queryName="ByName" >
<parameter paramName="1" value="Z"/>
</altJSONSQLProvider>
<dataGrid id="grid" controllerId="jsonSQL"/>
</page>
クラス・クエリを使用して SQL 文を指定する方法の詳細は、"Zen コンポーネントの使用法" の “クラス・クエリの参照” を参照してください。
<altJSONSQLProvider> コンポーネントは、以下の属性を定義します。
属性 | 説明 |
---|---|
arrayName |
出力配列の名前。既定値は、"children" です。 |
currPage |
プロバイダがサーバ側データ・ページングを使用している場合、これが現在のページの 1 から始まる番号です。 |
OnGetSQL |
これは、このプロバイダを操作する SQL クエリ (文字列) を返すコールバック・メソッドを指定します。これは、sqlOpens in a new tab プロパティの動作と同じです (置き換えられます)。このメソッドを使用すると、パラメータ値または criteriaOpens in a new tab プロパティを介して渡される検索条件に基づいてクエリを簡単に作成できます。 |
pageSize |
プロバイダがサーバ側データ・ページングを使用している場合、これが各ページ内のレコードの数です。 |
recordCount |
プロバイダがサーバ側データ・ページングを使用している場合、これがレコードの合計数です。 |
%WriteJSONFromSQL および %WriteJSONStreamFromSQL メソッドは、クラス・クエリとパラメータの使用もサポートします。最初の例は、%WriteJSONFromSQL を使用したクラス・クエリの使用を示しています。
set pid="Z"
set provider=##class(%ZEN.Auxiliary.altJSONSQLProvider).%New()
set provider.queryClass="Sample.Person"
set provider.queryName="ByName"
set param=##class(%ZEN.Auxiliary.parameter).%New()
set param.value=pid
do provider.parameters.SetAt(param,1)
do provider.%WriteJSONFromSQL("","",,1000,,provider)
quit
次の例では、%WriteJSONFromSQL に指定される SQL 文に 2 つのパラメータを指定しています。
set pid="Z"
set provider=##class(%ZEN.Auxiliary.altJSONSQLProvider).%New()
set query="Select * from Sample.Person where Name %STARTSWITH ? or Age > ?"
set provider.sql=query
set param=##class(%ZEN.Auxiliary.parameter).%New()
set param.value=pid
set param1=##class(%ZEN.Auxiliary.parameter).%New()
set param1.value=20
do provider.parameters.SetAt(param,1)
do provider.parameters.SetAt(param1,2)
do provider.%WriteJSONFromSQL("","",,1000,,provider)
quit
最後の例では、%WriteJSONStreamFromSQL に指定される SQL 文に 2 つのパラメータを指定しています。
set pid="Z"
set provider=##class(%ZEN.Auxiliary.altJSONSQLProvider).%New()
set query="Select * from Sample.Person where Name %STARTSWITH ? or Age > ?"
set provider.sql=query
set param=##class(%ZEN.Auxiliary.parameter).%New()
set param.value=pid
set param1=##class(%ZEN.Auxiliary.parameter).%New()
set param1.value=30
do provider.parameters.SetAt(param,1)
do provider.parameters.SetAt(param1,2)
do provider.%WriteJSONStreamFromSQL(.stream,"",,1000,,provider)
quit
Zen ページのイベント処理
onclick や onchange などのイベント・ハンドラを定義するコンポーネントが数多くあります。"Zen コンポーネントの使用法" の “Zen コントロール” の章で、<button>、<image>、<submit> などの Zen コントロール・コンポーネントの説明を参照してください。また、“クライアント側の関数、変数、およびオブジェクト” の、zenEvent の説明も参照してください。
ページを表示している間、Zen ではページの構築が完了するまで、すべてのイベントがトラップされます。これは、クライアント側のブラウザで zenPage オブジェクトの構築が完了するまで、ユーザが要素をクリックできないようにするためです。
Zen ページの URI パラメータ
Zen ページに値を渡すときに、URI パラメータを使用すると便利なことがあります。ZENURL データ型パラメータにより、この機能を有効にできます。
Zen ページ・クラスでプロパティを定義するときに、次のように ZENURL データ型パラメータにそれを適用するとします。
Property employeeID As %ZEN.Datatype.string(ZENURL="ID");
この例では、ID という名前の URI パラメータを、employeeID という名前のクラス・プロパティに割り当てています。URI をブラウザに渡してこの Zen ページを要求する場合、ID に指定された値は employeeID に割り当てられます。以下に例を示します。
MyApp.MyPage.cls?ID=48
次のコードが実行されます。
Set %page.employeeID = $GET(%request.Data("ID",1))
あるプロパティに割り当てられている URI パラメータが、そのプロパティの MAXVAL を超える値を持っているなどの理由で、プロパティの検証テストに合格しなかった場合、このページは表示されず、代わりにエラー・メッセージが表示されます。
Zen のレイアウト・ハンドラ
グループ・コンポーネントの子コンポーネントは、実際には %ZEN.LayoutManagerOpens in a new tab クラスでレイアウトされます。標準で提供されるレイアウト方針に加えて、さらにレイアウト方針を実装できます。独自のカスタム・レイアウト・ハンドラ・コードを使用してページを表示することが可能です。
さらに容易で短期間のアプリケーション開発を可能にするため、Zen はシンプルな組み込みレイアウト方針を提供しています。コンポーネントのレイアウトはページの左上から始まり、右下へと進みます。ユーザは垂直グループおよび水平グループの入れ子を操作することにより、短時間で多くの成果を得ることができます。
レイアウトの微調整が必要になることもあります。その場合は、最終的には、Zen で使用するレイアウト・ハンドラを独自に開発する方法が最良である可能性もあります。このような場合に備えて、Zen には onlayoutHandler コールバック・メソッドが用意されています。このクライアント側メソッドを定義しておくと、最初にページを表示するときと、その後、ページのサイズを変更するたびに呼び出されます。これにより、コンポーネントを含むページのサイズを変更するたびにコンポーネントのサイズと位置を調整するコードを定義できます。
以下はその例です。
ClientMethod onlayoutHandler(load) [ Language = javascript ]
{
// adjust size of lookout menu
var menu = zen('lookout');
// find div for titleBox & mainMenu
var title = zen('titleBox');
var divTitle = title.getEnclosingDiv();
// find height of window
var winHeight = zenGetWindowHeight();
// adjust size of menu
var sz = winHeight - (parseInt(divTitle.offsetHeight)) - 20;
menu.setSize(null,sz);
}
Zen ユーティリティ・メソッド
%ZEN.UtilsOpens in a new tab クラスには、頻繁に使用するさまざまな機能を実行するユーティリティ・メソッドが多数用意されています。これらのクラスの大半は、Zen ライブラリで内部的に使用されます。
SAMPLES ネームスペースにある ZENTest.LogPageOpens in a new tab は、これらのユーティリティ・メソッドをいくつか使用して、アプリケーションに対するログを有効にするかどうかをユーザが選択したとき、それに応答するページ・クラスの例です。このページ・クラスには次の各項目があります。
-
イベント・ログ表示の <tablePane> 定義、および次の <checkbox>
<checkbox id="cbEnabled" caption="Logging Enabled" onchange="zenPage.enabledChange(zenThis);"/>
-
次のクライアント側メソッド
ClientMethod enabledChange(cb) [ Language = javascript ] { this.EnableLog(cb.getValue()==1 ? true : false); this.refreshLog(); }
-
次の Zen メソッド
ClassMethod EnableLog(flag As %Boolean = "") As %Boolean [ ZenMethod ] { If (flag = "") { Set flag = ##class(%ZEN.Utils).%LoggingEnabled() } If (flag) { Do ##class(%ZEN.Utils).%StartLog() } Else { Do ##class(%ZEN.Utils).%StopLog() } Quit 1 }
この結果は次のようになります。
%ZEN.UtilsOpens in a new tab の詳細は、InterSystems のオンライン・ドキュメント・システムを開き、%SYS ネームスペースの [クラス・リファレンス情報] を選択します。