Zen Mojo チュートリアル
この章には、Zen Mojo の基本事項を理解するのに役立つチュートリアルが含まれています。以下のトピックについて説明します。
このチュートリアルでは、Zen Mojo<version number>Demos.ZIP ファイルに含まれている ZMbasics パッケージのサンプル・クラスを使用します。設定の詳細は、この ZIP ファイルに含まれている Readme.txt ファイルを参照してください。
チュートリアル 1:レイアウト・グラフ
このチュートリアルでは、簡単な Zen Mojo ページを参照しながら、レイアウト・グラフについて説明します。このチュートリアルは、以下の部分で構成されます。
チュートリアル 1:開始
このチュートリアルを開始するには、以下の手順を実行します。
-
スタジオを開き、SAMPLES ネームスペースに切り替えます。
-
[ビュー]→[ウェブページ] をクリックします。または、F5 キーを押します。
次のページが表示されます。
-
[Developer Details] ボタン をクリックします。このページに以下の内容が表示されます。
[Data] セクションには、ページのこの部分で現在使用できるデータが表示されます。この例では、使用可能なデータはありません。このセクションについては、次のチュートリアルで再度確認します。
[Layout] セクションには、ページのこの部分の表示内容をレイアウトするために使用される情報が表示されます。この情報は、レイアウト・グラフと呼ばれる JSON オブジェクトにも格納されています。このオブジェクトには、オブジェクトの配列である children という名前のプロパティがあります。
Important:[Developer Details] オプションでは、これらのオブジェクトはリテラル形式で表示されません。有効な JavaScript 構文は表示されません。
-
[Developer Details] ボタン を再度クリックすると、ページが通常どおりに表示されます。
このサンプルが機能するしくみ
このセクションでは、サンプルが機能するしくみについて説明します。以下のトピックについて説明します。
ページ定義
最初に、ページの定義方法を確認しましょう。ZMbasics.Tutorial1.HomePageOpens in a new tab には、次の XData ブロックがあります。
XData pageContents [ XMLNamespace = "http://www.intersystems.com/zen" ]
{
<pane xmlns="http://www.intersystems.com/zen"
xmlns:mojo="http://www.intersystems.com/zen/mojo" layout="none">
<mojo:documentView id="mainView"
developerMode="true"
ongetlayout="return zenPage.getContent('mainViewLayout',key,criteria);">
<mojo:mojoDefaultPageManager>
<mojo:HTML5Helper/>
</mojo:mojoDefaultPageManager>
</mojo:documentView>
</pane>
}
この定義は、pageContents ペインを制御します。このペインは、(ほとんどの場合) ユーザがカスタマイズする唯一の領域です。ここでは、pageContents ペインはページの中央にある大きな長方形ですが、ほとんどのプラグインでは、pageContents ペインはページ全体に合わせて自動的にサイズ変更されます。
pageContents ペインの内部にある各項目はコンポーネントであり、このペイン内に長方形の領域として表示されます。この pageContents ペインには、<mojo:documentView> のインスタンス (または単に documentView) である 1 つのコンポーネントが含まれています。
この documentView は以下のように定義されます。
-
id 属性は mainView です。この属性は、コンポーネントの一意識別子を決定します。
-
developerMode 属性は True です。これは、documentView に [Developer Details] ボタン が表示されることを意味します。
-
ongetlayout 属性は、この documentView の外観をレイアウトする方法を指定します。この属性は、[Developer Details] ビューの [Layout] セクション内の値に対応します。
コンポーネントは Zen の用語です。Zen Mojo ページには、他のコンポーネント (コンテンツ・プロバイダなど) を含めることもできますが、通常は documentView コンポーネント (複数も可) のみを直接操作します。このため、このドキュメントでは通常、より具体的な用語である documentView を使用します。
使用するプラグインによっては、ページに複数の documentView を含めることができますが、それ以外の場合は、1 つの documentView のみがサポートされます。一般に、ページ・マネージャ・プラグインがモバイル・デバイスでの使用を目的にしている場合、そのプラグインはページ全体を使用し、複数の documentView をサポートしません。
getContent() の概要
ongetlayout 属性は以下のように定義されます。
ongetlayout ="return zenPage.getContent('mainViewLayout',key,criteria);"
getContent() メソッドは、コンテンツ・オブジェクト (データ・オブジェクトまたはレイアウト・グラフ) を返す Zen Mojo のシステム・メソッドです。この例では、最初の引数 (providerName) のみが使用されています。documentView は、それぞれ固有のコンテンツ・オブジェクトを持つことができます。ここでは、ページ内に documentView が 1 つだけ存在し、この documentView は後述するように 1 つのコンテンツ・オブジェクト (mainViewLayout) を持つことができます。
getContent() メソッドは以下を実行します。
-
関連するテンプレート・クラスの onGetContent() メソッドを呼び出します。このメソッドがコンテンツを返した場合は、そのコンテンツが返されます。
Zen Mojo は、初期テンプレート・クラスを見つけるため、ページ・クラスの TEMPLATECLASS パラメータを調べます。
-
onGetContent() が NULL を返した場合は、ページ・キャッシュにコンテンツが含まれているかどうかが確認されます。含まれている場合は、そのコンテンツが返されます。
-
キャッシュ・コンテンツがない場合は、関連するテンプレート・クラスの %OnGetJSONContent() メソッドが呼び出され、その結果を使用してコンテンツが作成され、返されます。
onGetContent() メソッドと %OnGetJSONContent() メソッドは、テンプレート・クラスのアプリケーション固有のメソッドです。getContent() メソッドは、ページ・クラスのシステム・メソッドです。
documentView コンポーネントをレイアウトする方法
前のセクションで説明したように、getContent() は関連するテンプレート・クラスの onGetContent() メソッドを呼び出します。ここでは、テンプレート・クラスは ZMbasics.Tutorial1.TemplateOpens in a new tab であり、そのクラスの onGetContent() メソッドは以下のとおりです。
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;
}
return content;
}
myGetMainViewLayout() は、その名前からわかるように、アプリケーション固有のメソッドです。以下のように定義されます。
ClientMethod myGetMainViewLayout(key, criteria) [ Language = javascript ]
{
var myLayoutGraph = {};
//The standard technique is to have a switch/case construct that creates
//branches based on the key argument;
//In this case only one key value is possible, so there is no need to branch
myLayoutGraph = {
children: [
{ type: '$header', $content: 'Zen Mojo Tutorial 1'},
{ type: '$p', $content: 'This page displays some simple text.'},
{ type: '$p', $content: 'Here is another paragraph.' },
]
}
return myLayoutGraph;
}
このメソッドは、JSON オブジェクトである Zen Mojo レイアウト・グラフを返します。レイアウト・グラフには、レイアウト・オブジェクトの配列 (1 つの $header オブジェクトと 2 つの $p オブジェクト) を格納する children という名前のプロパティがあります。これらのレイアウト・オブジェクトは、ヘルパー・プラグインで定義されます。
Zen Mojo では、一般にこのレイアウトにリストされている順序で項目がレイアウトされるため、ここではヘッダが最上部に表示され、その下にパラグラフが表示されます。配置をより細かく制御するには、CSS を使用することをお勧めします。
ブラウザは、Zen Mojo レイアウト・グラフを (Zen Mojo が提供するその他の指示と共に) 使用し、HTML 5.0 を生成して、ページを表示します。
サンプルにおける配置の定義方法
既定のページ・マネージャを使用する場合は、ページ・クラスで adjustContentSize() メソッドを定義する必要があります。このメソッドの目的は、pageContents ペイン内の各 documentView のサイズと位置を指定することです。
このメソッドは、pageContents ペインの幅と高さを入力として受け取ります。これらのディメンションは、現在のサイズとローテーションによって異なります。このメソッドは、さらに入力引数 load を受け取ります。この引数は、ページがロードされている場合は 1、それ以外の場合は 0 になります。
ここでは、adjustContentSize() メソッドは以下のようになります。
ClientMethod adjustContentSize(load, width, height) [ Language = javascript ]
{
// This method should have an if{} block for each component.
var mainView = zen('mainView');
if (mainView) {
mainView.setSize(width, height);
var mainDiv = mainView.getEnclosingDiv();
mainDiv.style.top = '0px';
mainDiv.style.left = '0px';
}
}
構文 zen('mainView') は、ID が mainView である documentView への参照です。コンポーネントの配置を指定するため、このメソッドはコンポーネントのインスタンス・メソッドを呼び出し、コンポーネントのプロパティを設定します。
演習
テクノロジを習得するには、機能しているサンプルに独自の修正を加えることをお勧めします。次の演習を実行してください。
-
HTML ヘルパー・プラグインを含まないように pageContents の XData ブロックを変更します。ページ・クラスを再コンパイルしてページを再表示します。表示はどのようになりますか。その後、変更を元に戻して再コンパイルします。
-
myGetMainViewLayout() メソッドで、$header または $p オブジェクトをカスタマイズします。例えば、各オブジェクトの style 属性を設定します。この属性は、レイアウト・オブジェクトに適用するインライン CSS スタイルを指定します。
-
documentView の開発者モードを無効にして、ユーザの場合と同じようにページを表示します。ヒント:そのためには、pageContents の XData ブロックを変更します。
-
pageContents の XData ブロックで、documentView の id を mainView から mainViewNEW に変更して、再コンパイルします。この変更はページにどのような影響を及ぼしますか。この id を元の値に戻すことができない場合、ページを再度正しく表示するには、どのような追加の変更が必要ですか。
チュートリアル 2:データ・オブジェクト
このチュートリアルでは、もう少し複雑な Zen Mojo ページについて説明します。このチュートリアルは、以下の部分で構成されます。
チュートリアル 2:開始
このチュートリアルを開始するには、以下の手順を実行します。
-
スタジオの SAMPLES ネームスペースで、ZMbasics.Tutorial2.HomePageOpens in a new tab クラスを開きます。
-
[ビュー]→[ウェブページ] をクリックします。または、F5 キーを押します。
次のページが表示されます (表示されるデータは異なります)。
-
ページ下部の [Developer Details] ボタン をクリックします。ページの中央領域に以下の [Developer Details] ビューが表示されます。
[Data] セクションには、ページのこの部分で現在使用できるデータが表示されます。このデータは、データ・オブジェクトと呼ばれる JSON オブジェクトに格納されています。このオブジェクトには、personDOB および personName というプロパティがあります。
前のチュートリアルで説明したように、[Layout] セクションにはレイアウト・グラフに含まれる情報が表示されます。ここでは、レイアウト・グラフが [Data] セクションに表示される値を参照していることに注意してください。
このサンプルが機能するしくみ
このセクションでは、サンプルが機能するしくみについて説明します。以下のトピックについて説明します。
ページ定義
最初に、ページの定義方法を確認しましょう。ZMbasics.Tutorial2.HomePageOpens in a new tab には、次の XData ブロックがあります。
XData pageContents [ XMLNamespace = "http://www.intersystems.com/zen" ]
{
<pane xmlns="http://www.intersystems.com/zen"
xmlns:mojo="http://www.intersystems.com/zen/mojo" layout="none">
<mojo:documentView id="mainView"
developerMode="true"
ongetdata="return zenPage.getContent('mainViewData',key,criteria);"
ongetlayout="return zenPage.getContent('mainViewLayout',key,criteria);">
<mojo:mojoDefaultPageManager>
<mojo:HTML5Helper/>
</mojo:mojoDefaultPageManager>
</mojo:documentView>
</pane>
}
この定義には、前のサンプルにはなかった新しい要素が 1 つ含まれています。この documentView には、ongetdata 属性が指定されています。この属性は、この documentView で使用できるようにするデータをサーバから取得する方法を指定します。この属性は、[Developer Details] ビューの [Data] セクション内の値に対応します。
サンプルがサーバからデータを取得する方法
ongetdata 属性は、この documentView で使用するデータを取得する方法を指定します。この属性は、次のように指定されます。
ongetdata="return zenPage.getContent('mainViewData',key,criteria);"
前のチュートリアルで説明したように、getContent() は関連するテンプレート・クラスの onGetContent() メソッドを呼び出し、その引数をこのメソッドに渡します。ここでは、テンプレート・クラスは ZMbasics.Tutorial2.TemplateOpens in a new tab であり、その getContent() メソッドは以下のとおりです。
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;
}
return content;
}
ご覧のように、providerName 引数が mainViewData である場合、このメソッドは NULL を返します。ここでは、テンプレートの onGetContent() メソッドが NULL を返すため、同じクラスの %OnGetJSONContent() メソッドが Zen Mojo によって自動的に呼び出されます。この例では、このメソッドは以下のようになります。
ClassMethod %OnGetJSONContent(pProviderName As %String, pKey As %String, ByRef pParms,
Output pObject As %RegisteredObject, pCriteria As %RegisteredObject, pLoad As %Boolean = 0)
As %Status
{
// The standard technique is to have an outermost if/elseif construct
// based on the pProviderName argument; in this case there is only one
// possible value for pProviderName.
if (pProviderName = "mainViewData") {
// Within a pProviderName branch, the standard technique is to have an
// if/elseif construct based on the key argument.
// In this case, there are no keys, so there is no need to branch
set pObject = ##class(%ZEN.proxyObject).%New()
set tPerson = ##class(Sample.Person).%OpenId(1)
set pObject.personName=tPerson.Name
set pObject.personDOB=$zdate(tPerson.DOB,3)
} ; additional pProviderName branches would go here
quit $$$OK
}
}
このメソッドは、クライアントに返すデータを保持するため、%ZEN.ProxyObject のインスタンスを作成し、そのオブジェクトのプロパティを設定します。(%ZEN.ProxyObject クラスは、事前定義のプロパティを持たない代わりに、任意のプロパティを保持できる特殊用途のコンテナ・オブジェクトです。概要については、“Zen アプリケーションの開発” の “Zen プロキシ・オブジェクト” を参照してください。)
このメソッドは、%ZEN.ProxyObject を出力オブジェクトとして返します。このオブジェクトは Zen Mojo によって JSON オブジェクトに変換され、クライアントに渡されます。クライアントは、[Developer Details] ビューに表示されるデータを受け取ります。
サンプルがサーバからデータを取得する方法:JSON プロバイダ
サーバからデータを取得できるようにするには、もう 1 つの要素として PROVIDERLIST パラメータが必要です。このパラメータは、サーバ上で作成されるすべてのデータ・オブジェクトの名前をリストする必要があります。これには、%OnGetJSONContent() 内のメイン・ブランチを含める必要があります。
この例では、ページ・クラスでこのパラメータを次のように定義しています。
Parameter PROVIDERLIST = "mainViewData";
レイアウト・グラフの再確認
このテンプレートでは、次のメソッドによってこのページで使用するレイアウト・グラフを定義しています。
ClientMethod myGetMainViewLayout(key, criteria) [ Language = javascript ]
{
var myLayoutGraph = {};
//The standard technique is to have a switch/case construct based on the key argument;
//In this case only one key value is possible, so there is to branch
myLayoutGraph = {
children: [
{ type: '$header', $content:'Zen Mojo Tutorial 2'},
{ type: '$p', $content:'Below are details for the first person in Sample.Person.'},
{ type: '$p', title:'Name', $content:'=[personName]' },
{ type: '$p', title:'Birth Date', $content:'=[personDOB]' }
]
}
return myLayoutGraph;
}
最後の 2 つの $p オブジェクトがデータ・オブジェクトから取得したデータを表示することに注意してください。構文 =[name] は、データ・オブジェクトの特定のプロパティ値を取得します。
演習
テクノロジを習得するには、機能しているサンプルに独自の修正を加えることをお勧めします。次の演習を実行してください。
-
追加のデータを返すようにテンプレートを変更します。例えば、%OnGetJSONContent() の適切な位置に次の行を追加します。
set pObject.HomeCity = tPerson.Home.City set pObject.FavoriteColors = tPerson.FavoriteColors
その後、テンプレート・クラスを再コンパイルし、Zen Mojo ページを表示して、[Developer Details] を表示します。
-
新しいデータを表示するようにテンプレート・クラスの myGetMainViewLayout() メソッドを変更します。例えば、'=[personDOB]' } の後にコンマを追加し、次の行を追加します。
{ type: '$p', $content:'=[HomeCity]' }, { type: '$p', $content:'=[FavoriteColors]' }
その後、テンプレート・クラスを再コンパイルし、Zen Mojo ページを表示します。
-
myGetMainViewLayout() メソッドで、$header または $p オブジェクトをカスタマイズします。
-
PROVIDERLIST パラメータの値を mainViewData から mainViewNEWProvider に変更して、再コンパイルします。この変更はページにどのような影響を及ぼしますか。PROVIDERLIST を元の値に戻すことができない場合、ページを再度正しく表示するには、どのような追加の変更が必要ですか。
チュートリアル 3:イベント処理
このチュートリアルでは、Zen Mojo のイベント処理に焦点を当てて説明します。このチュートリアルは、以下の部分で構成されます。
チュートリアル 3:開始
このチュートリアルを開始するには、以下の手順を実行します。
-
スタジオの SAMPLES ネームスペースで、ZMbasics.Tutorial3.HomePageOpens in a new tab クラスを開きます。
-
[ビュー]→[ウェブページ] をクリックします。または、F5 キーを押します。
次のページが表示されます (表示されるデータは異なります)。
-
[Show Person 2] ボタンを押すと、表示が変更されるのがわかります。
このサンプルが機能するしくみ
このセクションでは、サンプルが機能するしくみについて説明します。このサンプルは、前のチュートリアルのサンプルとは次の 2 つの点で異なります。
-
レイアウト・グラフにボタン要素が含まれています。
-
テンプレート・クラスに onselect() メソッドが定義されています。
まず、テンプレート・クラスの次のメソッドによって提供されるレイアウト・グラフを調べてみましょう。
ClientMethod myGetMainViewLayout(key, criteria) [ Language = javascript ]
{
var myLayoutGraph = {};
//The standard technique is to have a switch/case construct based on the key argument.
//In this case, the layout is not key-specific layout, so there is no need to branch.
myLayoutGraph = {
children: [
{ type: '$header', $content: 'Zen Mojo Tutorial 3'},
{ type: '$p'},
{ type: '$button', $content:'Show Person 1', key:'showPerson1'},
{ type: '$p'},
{ type: '$button', $content:'Show Person 2', key:'showPerson2'},
{ type: '$p'},
{ type: '$div', key:'person1',
children:[
{ type: '$p', title:'Name', $content:'=[person1Name]' },
{ type: '$p', title:'Birth Date', $content:'=[person1DOB]' }
]},
{ type: '$div', key:'person2', hidden:true,
children:[
{ type: '$p', title:'Name', $content:'=[person2Name]' },
{ type: '$p', title:'Birth Date', $content:'=[person2DOB]' }
]},
]
}
return myLayoutGraph;
}
このレイアウト・グラフは、2 つの $button レイアウト・オブジェクトを含み、各オブジェクトのキー値を指定していることがわかります。このレイアウト・グラフでは、ボタンの後に 2 つの $div オブジェクトがあり、1 つは最初から表示され、もう 1 つは非表示になっています。
次に、onselect() メソッドを調べてみましょう。ユーザがページ上の項目を選択すると、Zen Mojo によってこのメソッドが自動的に呼び出されます。このメソッドの定義は以下のとおりです。
ClientMethod onselect(key, value, docViewId) [ Language = javascript ]
{
console.log('in '+docViewId+ ' select: ' + key + ' value: ' + value);
if (docViewId=='mainView') {
var person1=zen('mainView').getItemByKey('person1');
var person2=zen('mainView').getItemByKey('person2');
if (key=='showPerson1') {
person1.$show();
person2.$hide();
} else if (key=='showPerson2') {
person1.$hide();
person2.$show();
}
}
}
このメソッドは、選択イベントが発生した documentView の ID を引数として受け取ります。これにより、各 documentView の動作をカスタマイズできます。ここでは、documentView は 1 つしかありません。残りの引数は、選択された項目のキーと値です。
console.log 行は、JavaScript コンソールに行を書き込みます。ここでは、この行は onselect() メソッドに渡された値に関する情報を提供するだけです。
このメソッドは、zen() 構文を使用して documentView コンポーネントにアクセスし、getItemByKey() メソッドを使用してレイアウト・グラフの特定の項目にアクセスします。
このメソッドは、選択したキーに応じてレイアウト・グラフのどの部分を表示するかを制御します。$show() メソッドと $hide() メソッドは HTML5 ヘルパー・プラグインから提供されることに注意してください。他のツールは他のヘルパー・プラグインから提供されます。各プラグインの詳細は、“Zen Mojo プラグインの使用法” を参照してください。
演習
-
使用しているブラウザの JavaScript コンソールを表示します。詳細はブラウザによって異なりますが、このコンソールは一般に他の開発者ツールに含まれています。Zen Mojo ページ上のボタンをクリックし、このコンソールで対応するログ・エントリを確認します。
-
表示にボタンをもう 1 つ追加します。このボタンでは、2 つの $div オブジェクトを両方とも表示します。
-
さらに、Sample.PersonOpens in a new tab から 3 人目の担当者を表示するための専用のボタンを追加します。