コールバックとイベント・ハンドラの概要
この章では、Zen Mojo ページに適用されるすべてのイベント・ハンドラとコールバックの概要を示します。ページの動作を定義するには、これらの項目の一部またはすべてを実装する必要があります。この章では、以下のトピックについて説明します。
ongetdata および ongetlayout コールバック属性
documentView のもっとも基本的なコールバック属性は、ongetdata と ongetlayout の 2 つです。これらについては、このドキュメントですでに紹介しました。
これらのコールバックがいつ使用されるか
Zen Mojo ページが表示されるか、メソッド updateLayout() が実行されるときに、Zen Mojo は ongetdata と ongetlayout の両方を検査して、これらのコールバックに指定されたコードを実行します。ongetdata が最初に実行され、続いて ongetlayout が実行されます (ただし、以下の注を参照)。
通常、これらのコールバックはページ・メソッド getContent() を呼び出します。
両方のコールバック内で、変数 key と value を取得できます。変数 key は選択したレイアウト・オブジェクトのキー (存在する場合) と等しく、変数 value は選択したレイアウト・オブジェクト (存在する場合) の値です。
さらに、ongetlayout 内では、ongetdata から返されるデータ・オブジェクトにアクセスできます (ただし、以下の注を参照)。
注:
-
ongetlayout が sourceData オブジェクトを含むレイアウト・グラフを返す場合、ongetdata コールバックは呼び出されません。
-
ongetdata コールバックは、指定されたキーのデータがキャッシュに含まれている場合には呼び出されません。
Zen Mojo は、データ・オブジェクトとレイアウト・グラフの両方をキャッシュに入れます。指定した documentView のキャッシュを無効にすることができます。このためには、documentView の invalidate() メソッドを使用します。以下に例を示します。
var mainView = zen('mainView'); mainView.invalidate();
-
ongetdata コールバックのみを呼び出すこともできます。このためには、documentView の getSourceData() メソッドを使用します。以下に例を示します。
var mainView = zen('mainView'); var data = mainView.getSourceData();
getSourceData() メソッドは、documentView インスタンスのソース・データを返します。このデータは、レイアウト・グラフ (sourceData プロパティを定義している場合)、現在のレベルのデータ・キャッシュ、または ongetdata コールバックから取得される場合があります。
ongetdata または ongetlayout の指定
これらのコールバック属性のいずれかを定義するには、以下の一般的な手順を使用します。
-
documentView の定義の中で属性の値を指定します。
ほとんどの場合、以下の例に示すように、値はページの getContent() メソッドを呼び出す JavaScript 式です。
<mojo:documentView id="mainView" ongetlayout = "return zenPage.getContent('layout',key,criteria);" ongetdata = "return zenPage.getContent('data',key,criteria);"> ... </mojo:documentView>
-
関連したテンプレート・クラスで、onGetContent() メソッドと %OnGetJSONContent() メソッドを実装します。以下のセクションでは、これらのメソッドについて詳しく説明します。
onGetContent() と %OnGetJSONContent() の概要については、本書ですでに説明した “テンプレート・システム” を参照してください。
getContent() の詳細
ongetdata および ongetlayout コールバック属性は、通常はページの getContent() メソッドを呼び出します。このセクションでは、このメソッドの詳細を説明します。
(他のシナリオでこのメソッドを呼び出しても役に立つ場合があります。例については、サンプル ZMdemo.LoadAsync.baseTemplateOpens in a new tab 内の onselect() メソッドを参照してください。)
getContent() メソッドは、コンテンツ・オブジェクト (データ・オブジェクトまたはレイアウト・グラフ) を返します。このメソッドには、以下の引数があります。
getContent(providerName, key, criteria, force, notify)
以下はその説明です。
-
providerName は、取得するコンテンツ・オブジェクトの名前を指定します (“Zen Mojo テンプレート” の章の “コンテンツ・オブジェクト” を参照)。documentView は、それぞれ固有のコンテンツ・オブジェクトを持つことができます。
-
key は、コンテンツの特定のバージョンを示す短い一意の名前です。
-
criteria は、コンテンツ・テンプレートに渡す追加情報を含んでいます。これは、ユーザによって入力された検索文字列である場合も、コード内部で使用されるその他の条件である場合もあります。
-
force は、サーバからコンテンツを再ロードするかどうかを指定します。
-
notify は、NULL または関数です。この引数が関数の場合、ページはデータをサーバに非同期に送信します (同期的でなく)。その後、データが送信されると、ページはこの引数によって指定された関数を実行します。
例については、サンプル ZMdemo.LoadAsync.baseTemplateOpens in a new tab 内の onselect() メソッドを参照してください。
getContent() メソッドは以下を実行します。
-
関連するテンプレート・クラスの onGetContent() メソッドを呼び出します。このメソッドがコンテンツを返した場合は、そのコンテンツが返されます。
Zen Mojo は、初期テンプレート・クラスを見つけるため、ページ・クラスの TEMPLATECLASS パラメータを調べます。
-
onGetContent() が NULL を返した場合は、ページ・キャッシュにコンテンツが含まれているかどうかが確認されます。含まれている場合は、そのコンテンツが返されます。
-
キャッシュ・コンテンツがない場合は、関連するテンプレート・クラスの %OnGetJSONContent() メソッドが呼び出され、その結果を使用してコンテンツが作成され、返されます。
この動作の図については、このドキュメントですでに説明した “テンプレート・システム,” を参照してください。
onGetContent() の定義
それぞれの Zen Mojo テンプレート・クラスは、onGetContent() メソッドを定義する必要があります。このメソッドは、コンテンツ・オブジェクトを返すディスパッチャです。このメソッドには、以下のシグニチャがあります。
ClientMethod onGetContent(providerName, key, criteria) [ Language = javascript ]
以下はその説明です。
-
providerName は、返すコンテンツ・オブジェクトを指定します。
-
key は、コンテンツ・オブジェクトを取得する際に使用するキーを指定します。
-
criteria は、コンテンツ・オブジェクトを取得する際に使用する追加の条件を指定します。
このメソッドでの標準的な手法は、providerName 引数を使用する外部分岐文を使用することです。
-
providerName がレイアウト・グラフに対応する場合、onGetContent() は適切なレイアウト・メソッドを呼び出す必要があります。“レイアウト・メソッドの定義” の章を参照してください。
また、onGetContent() は key 引数と criteria 引数をそのメソッドに渡す必要があります。
-
providerName がデータ・オブジェクトに対応する場合、onGetContent() は NULL を返す必要があります。
この場合、Zen Mojo はこのクラス内の %OnGetJSONContent() を呼び出してオブジェクトを取得します (次のサブセクション “Defining %OnGetJSONContent()” を参照)。
以下に例を示します。このシナリオでは、mainViewLayout と leftViewLayout はレイアウト・グラフのキーです。switch 文には、これらのレイアウト・グラフの分岐のみが含まれていることに注意してください。したがって、データ・オブジェクトのキーを指定して呼び出された場合、このメソッドは NULL を返します。
ClientMethod onGetContent(providerName, key, criteria) [ Language = javascript ]
{
var content = null;
// dispatch to convenient methods
// if content is null, then the %OnGetJSONContent method will be called
switch(providerName) {
case 'mainViewLayout':
content = this.myGetMainViewLayout(key,criteria);
break;
case 'leftViewLayout':
content = this.myGetLeftViewLayout(key,criteria);
break;
}
return content;
}
%OnGetJSONContent() の定義
ほとんどの場合、それぞれの Zen Mojo テンプレート・クラスは、%OnGetJSONContent() メソッドを定義する必要があります。このメソッドは、要求されたデータ・オブジェクトを出力パラメータとして返す必要があります。このメソッドには、以下のシグニチャがあります。
ClassMethod %OnGetJSONContent(pProviderName As %String,
pKey As %String,
ByRef pParms,
Output pObject As %RegisteredObject,
pCriteria As %RegisteredObject,
pLoad As %Boolean = 0) As %Status
以下はその説明です。
-
pProviderName は、返すデータ・オブジェクトを指定します。
-
pKey は、データ・オブジェクトを取得する際に使用するキーを指定します。
-
pParms は現在は使用されていません。
-
pObject は、クライアントに返すデータを含む %ZEN.ProxyObject のインスタンスです。
%ZEN.ProxyObject クラスは、事前定義のプロパティを持たない、特殊用途のコンテナ・オブジェクトです。概要については、"Zen アプリケーションの開発" の “Zen プロキシ・オブジェクト” を参照してください。
-
pCriteria は、クライアントから送られる追加の条件です。
-
pLoad は、データをロードするかどうかを指定します。この引数は、ページが初めて提供されるとき、True に設定されます。
このメソッドでの標準的な手法は、pProviderName 引数を使用する外部分岐文を使用することです。
その後、いずれかの pProviderName 分岐内で、内部分岐文を使用します。この文は、pKey 引数を検査し、その引数に応じて別の pObject を作成します。以下に示す例では、pProviderName の可能な値はただ 1 つですが、pKey には可能な値が複数あります。
ClassMethod %OnGetJSONContent(pProviderName As %String, pKey As %String, ByRef pParms,
Output pObject As %RegisteredObject, pCriteria As %RegisteredObject,
pLoad As %Boolean = 0) As %Status
{
if (pProviderName = "mainViewData") {
//nothing to return for MyButton1 so there is no branch for that
if (pKey = "MyButton2") {
//create proxy object that the Zen Mojo will convert to a JSON string
//and send to the client
set pObject = ##class(%ZEN.proxyObject).%New()
set random=$R(100)+1
set tPerson = ##class(Sample.Person).%OpenId(random)
set pObject.personName=tPerson.Name
set pObject.personDOB=$zdate(tPerson.DOB,3)
}
elseif (pKey = "MyButton3") {
//create proxy object that the Zen Mojo will convert to a JSON string
//and send to the client
set pObject = ##class(%ZEN.proxyObject).%New()
set tList = ##class(%Library.ListOfObjects).%New()
set pObject.children = tList
For i=1:1:5 {
// we could retrieve the same company more than once this way
// but this is a demo so that doesn't matter
set tNumber=$RANDOM(20)+1
set tCompany = ##class(Sample.Company).%OpenId(tNumber)
set tCompanyData = ##class(%ZEN.proxyObject).%New()
set tCompanyData.companyName = tCompany.Name
set tCompanyData.companyMission = tCompany.Mission
set tCompanyData.companyRevenue = tCompany.Revenue
Do tList.Insert(tCompanyData)
}
set pObject.rowCount = tList.Count()
}
} ; additional pProviderName branches would go here
quit $$$OK
}
その他のコールバック属性
Zen Mojo は、documentView のコールバック属性を他にもいくつか提供しています。
-
onload
設定ロジックを実行するために使用されます。例えば、localStorage に基づいて初期ドキュメントとレイアウト・キーを設定できます。このコールバックは、documentView の初回のレンダリングが行われる前にのみ呼び出されます。
-
onrender
documentView がレンダリング中であることを通知します。
-
onresolvemethod
レイアウト・グラフで使用できるメソッドを定義できます (“レイアウト・メソッドの定義” の章の “レイアウト・グラフでのテンプレート・メソッドの呼び出し” を参照)。
-
onresolvepluginconflicts
プラグインの登録時に何らかの競合が発生した場合に、プラグイン競合に関する情報を提供します。詳細は、"Zen Mojo プラグインの使用法" の “プラグイン競合の検出および解決” を参照してください。
これらのコールバック属性を使用するには、ページで使用される documentView の属性に値を指定します。ほとんどの場合、値はテンプレート・クラスに実装したメソッドを呼び出す式です。以下に例を示します。
onresolvemethod="return zenPage.getTemplate().resolve(context,which);"
ここで getTemplate() は、ページに関連した現在のテンプレートのインスタンスに対する参照を返す basePage のメソッドです。
代わりに、ページ・クラスに含まれる同名の単純なラッパ・メソッドを呼び出すことにより、間接的に呼び出すこともできます。必要な場合は、ページ・クラス内でコールバック・メソッド自体を実装できますが、すべてのアプリケーション・ロジックをテンプレート・クラスに含めることをお勧めします。
イベント・ハンドラ
ページでイベントが発生すると、Zen Mojo は関連したテンプレート・クラス内のイベント・ハンドラを自動的に呼び出します。Zen Mojo のイベント・ハンドラは、onselect()、onchange()、および onevent() の各メソッドで、既定ではこれらに動作はありません。ページを対話式にするために、これらのメソッドはテンプレート・クラス内で定義します。
イベントがサポートされる場所
各プラグインのイベントは、ユーザ対話に使用されるレイアウト・オブジェクト内でサポートされます (既定)。つまり、ボタン、メニュー、スライダなどのコントロールを表現するレイアウト・オブジェクトはイベントをサポートし、プラグインはこれらのオブジェクトに対するイベント処理を挿入します。静的要素を表すレイアウト・オブジェクトは、イベントをサポートしません。
指定したレイアウト・オブジェクトに対して、イベント処理の挿入を抑止できます。このためには、必要に応じてそのレイアウト・オブジェクトの以下に示す属性を 1 つ以上指定します。
-
$ignoreSelect — この属性を True として指定すると、レイアウト・オブジェクトには onselect ハンドラが関連付けられません (onselect() は無視されます)。既定値は False です。
-
$ignoreChange — この属性を True として指定すると、レイアウト・オブジェクトには onchange ハンドラが関連付けられません (onchange() は無視されます)。既定値は False で、コントロールを表すレイアウト・オブジェクトには onchange ハンドラが関連付けられます。
-
$ignoreEvent — この属性を True として指定すると、レイアウト・オブジェクトには汎用イベント・ハンドラが関連付けられません (onevent() は無視されます)。既定値は False です。
イベント・ハンドラの実装
テンプレート・クラス内で、以下のイベント・ハンドラ・メソッドの一部またはすべてを定義します。標準的な実装では、これらのメソッドによってページまたは documentView インスタンスが必要に応じて変更されます。
ClientMethod onselect(key, value, docViewId) [ Language = javascript ]
ユーザが documentView 内でレイアウト・オブジェクトを選択したときのページの動作を定義します。引数は以下のとおりです。
-
key — 選択されたレイアウト・オブジェクトのキー。
-
value — レイアウト・オブジェクトの値 (存在する場合)。
-
docViewId — documentView の ID。
ClientMethod onchange(key, value, final, docViewId) [ Language = javascript ]
ユーザが documentView 内でレイアウト・オブジェクトの値を変更したときのページの動作を定義します。引数は以下のとおりです。
-
key — 変更されたレイアウト・オブジェクトのキー。
-
value — レイアウト・オブジェクトの新しい値。
-
final — 渡された値が最終の値であるかどうかを示します。
-
docViewId — documentView の ID。
ClientMethod onevent(eventType, key, value, docViewId) [ Language = javascript ]
documentView 内で別のタイプのイベントが発生したときのページの動作を定義します (選択または変更以外のイベント)。引数は以下のとおりです。
-
evtType — イベントのタイプ。イベント・タイプについては、"Zen アプリケーションの開発" の “zenEvent” を参照してください。
-
key — イベントを発生させたレイアウト・オブジェクトのキー。
-
value — そのオブジェクトの値 (存在する場合)。
-
docViewId — documentView の ID。