利用したい機能の読み込み
次に、機能に関するモジュールの読み込みについて説明します。Dijitの機能はDojo Toolkit本体とは別に、モジュールとして提供されるため、利用したい機能については明示的に指定して読み込むための設定を行う必要があります。このための記述にZend_DojoビューヘルパのrequireModule
メソッドを利用します(リスト4)。
... class IndexController extends Zend_Controller_Action { ... public function indexAction() { $dojo = $this->view->dojo(); //(1)Tabレイアウト用 $dojo->requireModule('dijit.layout.TabContainer'); $dojo->requireModule('dijit.layout.ContentPane'); //(2)ComboBox用 $dojo->requireModule('dojo.data.ItemFileReadStore'); $dojo->requireModule('dijit.form.ComboBox'); }
リスト4では、DojoビューヘルパのrequireModule
メソッドで、利用したいDijitのモジュールの読み込みのための設定を行っています。ここでは、サンプルで利用しているTabレイアウトとComboBoxのためのモジュールの読み込みを行っています。
モジュールの読み込みはDojo Toolkitのdojo.require
メソッドで行うことができますが、このdojo.require
を出力するように設定するのがrequireModule
などのメソッドです。この記述によって、ビュースクリプトの処理の際に、リスト5のような出力が行われます:
<script type="text/javascript"> //<!-- dojo.require("dijit.form.TabContainer"); dojo.require("dijit.form.Contentpane"); dojo.require("dojo.data.ItemFileReadStore"); dojo.require("dijit.form.ComboBox"); //-->
このDojoモジュールを読み込むための設定関係のメソッドには、次のようなものがあります。
メソッド名 | 引数 | 説明 |
requireModule | $module | モジュール$moduleを読み込むように設定 |
getModules | (なし) | 読み込むように設定されているモジュールのリストを返す |
registerModulePath | $module, $path | あるモジュール$moduleが設置されている場所$pathを指定 |
getModulePaths | (なし) | 登録されているモジュールの設置場所のリストを返す |
Dijitの使用法の指定
最後に、Dojo Toolkitの使用法の設定について説明します。実は、Dojo Toolkitにはモードが2つあり、それぞれ「プログラム的な使用法」と「宣言的な使用法」と呼ばれています。Zend_Dojoはどちらの使用法にも対応しており、どちらを使用しているかをほとんど意識しないで済むようになっていますが、それぞれ多少挙動が違う点がありますので、ここで説明します。
プログラム的な使用法では、Dijitに関する記述は基本的にヘッダのJavaScript内に行われ、HTMLの本体の部分には「どのDijitがどこに配置されるべきか」だけを示すタグが置かれることになります。一方、宣言的な使用法では、Dijitに関する記述はHTML本体の中のタグの中に、標準外のタグ属性として記述されることになります。少し分かりにくいので、実際に出力されるHTMLを見てみましょう。まず、プログラム的な使用法の例です(一部整形してあります)。
<html> <head> ... <script type="text/javascript"> //<!-- ... dojo.addOnLoad(function() {//(1)ページ読み込み時の処理 dojo.forEach(zendDijits, function(info) {//ZendDijitsの各要素について処理 var n = dojo.byId(info.id); if (null != n) { dojo.attr(n, dojo.mixin({ id: info.id }, info.params)); } }); dojo.parser.parse(); }); //(2)ComboBox に関する記述 var zendDijits = [{"id":"combobox","params":{"dojoType":"dijit.form.ComboBox"}}]; //--> </script></head> <body class="tundra"> ... <!--(3) ComboBoxが配置される場所 --> <select name="combobox" id="combobox"> <option value="alpha" label="A" selected="selected">A</option> <option value="beta" label="B">B</option> </select> ... </body> </html>
プログラム的な使用法ではどのようなDijitを利用するかはヘッダ内のJavaScriptに、そのDijitをどこに配置するのかは本文中に記述されます。(1)では、まずdojo.addOnLoad
関数で、ページ読み込み時に行う処理を登録しています。ここで登録されているのが、「dojo.forEach
」と「dojo.parser.parse
」です。このdojo.forEach
内では、配列「zendDijits
」の各要素に記述されているとおりにDijitの設定をしています。その直後にあるdojo.parser.parse
は、その設定を実際に反映させるための処理を行います。
このzendDijits
は(2)で定義されており、各要素がDijitの各要素に関する設定になっています。この例では要素はComboBoxに関するもの一つで、IDが「combobox」であるオブジェクトのdojoType
属性が「dijit.form.ComboBox
」であると指定しています。その、IDがcomboboxであるオブジェクトの実体は本文の中の(3)に配置されています。
処理の流れとしては、ページ全体が読み込まれ準備が整ったら、(2)にある記述に従って(1)のdojo.addOnLoad
内で各オブジェクトの属性に関する設定が準備され、その後のdojo.parser.parse
で各オブジェクトの属性が実際に設定されます。そうすると(3)のにあるselect要素がDijitのComboBoxとして扱われるようになります。
一方、宣言的な使用法では、Dijitの要素に関する記述は本文中に「宣言」されています。
<html> ... <body class="tundra"> ... <select name="combobox" id="combobox" dojoType="dijit.form.ComboBox"> <option value="alpha" label="A" selected="selected">A</option> <option value="beta" label="B">B</option> </select> ... </body> </html>
宣言的な使用法では「dojoType」なる標準外のタグ属性を利用して、どのようなDijitを利用するのかを指定しています。
このように、プログラム的な使用法と宣言的な使用法とでは、出力されるHTMLに大きな違いがあります。では、利用する上ではどのような違いがあるのでしょうか? 一番気にする必要があるのは、プログラム的な使用をする場合ビュースクリプトでヘッダを出力する前に、どのようなDijitを使うかを宣言しておく必要があるということです。つまり、宣言的な使用法ではビュースクリプトの、オブジェクトが配置される場所に直接Dijitに関する記述をすることができるのに対し、プログラム的な使用法ではあらかじめアクションスクリプト内などで、Dijitを生成しておく必要があります。
それ以外の細かい違いについては、Zend_Dojoを利用する上ではあまり意識する必要はないはずですが、筆者の個人的な感想を含め、メリット/デメリットをまとめてみました。
項目 | プログラム的 | 宣言的 | 説明 |
HTMLの正当性 | ○ | × | 宣言的な使用法では標準外のタグ属性を利用 |
出力HTMLの読みやすさ | × | ○ | 記述が分散される |
ドキュメント | × | ○ | Dojo Toolkitの解説は宣言的なものを前提にしたものが多い |
実は、Zend_Dojoは標準ではプログラム的な使用法を利用するように設定されています。しかし、出力されたHTMLを見ながらデバッグをすることを考えた場合には宣言的な使用法の方がメリットが多いので、サンプルは宣言的な使用法を使っています。
この使用法を設定するのが、Zend_Dojo_View_Helper
の静的メソッド、setUseDeclarative
とsetUseProgrammatic
です。
class IndexController extends Zend_Controller_Action { ... public function init() { ... $view = $this->view; ... Zend_Dojo::enableView($view); ... //宣言的に使用する Zend_Dojo_View_Helper_Dojo::setUseDeclarative(); }