japan.internet.com
japan.internet.com メンバーID
Twitter
Facebook
RSS
ピックアップ
2009年10月2日 10:00

EXTJS 俯瞰

■はじめに
前回のコラムでは、EXTJS の紹介とメッセージボックスを表示するサンプルにて、どのように記述を行えばよいかをご説明しました。

今回は、EXTJS の各 API がどのような形で構成されているか、また、細かい部分ではありますが、比較的便利だと思われる機能をご紹介していきたいと思います。

■デバッガ準備
このコラムのように JavaScript を多用するようなウェブアプリケーションの場合、JavaScript デバッガは、ほぼ必須でしょう。Firefox には、Firebug というデバッガがアドインで用意されていますので、入手されることをお勧めします。

■API の構成
EXTJS の各 API は全てクラス化されています。よって、オブジェクト指向プログラミングの知識が、ある程度必要となります。EXTJS の各クラスは、後述する名前空間の概念を使い、Ext クラスを頂点として、関連するクラス毎にツリー状で構成されています。

また各クラスは、何層かに渡りクラス継承を利用して構成されています。特にウィジェット系のクラスは、クラス継承の段数が多くなっています。

まずは、前回コラムの中でご紹介した API ドキュメント(日本語版英語版)を参照してください。左側のツリービューが、各クラスがどのようにツリー状に構成されているかを示しています。例えば、GridPanel クラスを利用した場合、この階層に沿って、

var grid = new Ext.grid.GridPanel({・・・});

と記述をすることで利用できます。

API ドキュメント中の Panel クラスの記述を参照してください。右側にそのクラスにおけるプロパティやメソッドの一覧が表示されるかと思います。右上の隅に、このクラスがどのようなクラスを継承しているかが示されているかと思います。

各クラスの API の説明は、大抵の場合、以下のセクションから構成されています。

項目名
内容
コンフィグオプション(Config Options)
このクラスのコンストラクタに対するパラメータのことです。
必須のものもありますが、大抵はオプション(省略可能)なので、必要と思われる項目のみをピックアップして、連想配列の形でコンストラクタパラメータとして渡すことになります。
なお、スタティッククラス(API上ではシングルトンと称しています)の場合には、この項目が存在しないことがあります。
プロパティ(Public Properties)
このクラスがインスタンス化された際に利用可能なプロパティの一覧です。
一部、スタティックプロパティが記載されていることがあります。
メソッド(Public Methods)
このクラスがインスタンス化された際に利用可能なメソッドの一覧です。
一部、スタティックメソッドが記載されていることがあります。
イベント(Public Events)
このクラスで受け取ることのできるイベントの一覧です。
イベントを受け取らないクラスの場合、記載がないことがあります。


■名前空間

EXTJS では、名前空間(ネームスペース)の概念が取り入れられています。この名前空間を用いて、EXTJS は、共通する内容毎に整理したクラスライブラリとして構成されています。全ての EXTJS コンポーネントは全て Ext というスタティッククラス兼名前空間の配下にまとめられています。

名前空間は、ウェブアプリケーション開発者が自由に作成できるようになっています。

Ext.namespace(‘hoge’);

上記は、Ext.namespace() メソッドを使用することで、「hoge」という名前空間を作成しています。この機能を用いることで、他の開発者が作成したコンポーネントとの(クラス名重複などによる)干渉を防ぐことができます。

■Ajax 機能
この種のフレームワークでは Ajax による通信が行える機能が大抵は盛り込まれていますが、EXTJS にも盛り込まれています。EXTJS における Ajax 利用の場合、以下のように Ext.Ajax クラスを使うのが便利でしょう。

以下は、クライアント側の HTML コードのサンプルです。

<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <title>Ajaxサンプル</title>
 
 <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
 
 <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>
 <script type="text/javascript" src="extjs/ext-all-debug.js"></script>
 
 <script type="text/javascript">
    Ext.BLANK_IMAGE_URL = 'extjs/resources/images/default/s.gif';
   
    function requestAjax()
    {
        Ext.MessageBox.wait( '計算中...' );
       
        Ext.Ajax.request( {
            method: 'POST',
            url:     '/svrajax.php',
            params: { lval: 10, ope: '+', rval: 11 },
            success: responseSuccess,
            failure: responseFailure
        } );
    }
   
   
    function responseSuccess(response, options)
    {
        Ext.MessageBox.hide();
       
        var resData = response.responseText;
        Ext.MessageBox.alert( 'Ajaxサンプル', '応答結果:\n' + resData );
    }
   
   
    function responseFailure(response, options)
    {
        Ext.MessageBox.hide();
       
        Ext.MessageBox.alert( 'Ajaxサンプル', '通信が失敗しました' );
    }
 </script>
</head>
 
<body>
 <input type="button" value="計算開始" onClick="requestAjax();">
</body>
</html>


また、以下は Ajax での通信を受け取り何らかの応答を返すサーバ側コードです。今回は PHP にてサンプルを用意しました。このサンプルを実行される場合、ファイル名は、「svrajax.php」としてください。

<?php
//
//waitメッセージボックス表示のため、waitを入れる。
//
sleep( 10 );
 
//
//ajaxにて送信された各パラメータ値を取得
//
$lval = ( isset($_POST['lval']) ? $_POST['lval'] : null );
$ope = ( isset($_POST['ope']) ? $_POST['ope'] : null );
$rval = ( isset($_POST['rval']) ? $_POST['rval'] : null );
 
//
//計算を行う。演算子が未定義のものはエラーステータスで応答する
//
switch( $ope ){
       case '+': $result = $lval + $rval; break;
       case '-': $result = $lval - $rval; break;
       case '*': $result = $lval * $rval; break;
       case '/': $result = $lval / $rval; break;
       default: header( 'HTTP/1.0 500 Inernal Server Error' ); exit;
}
 
//
//計算結果を返す
//
echo $result;
?>


このサンプルは、クライアント側コードより、lval、ope、rval の各パラメータ値を送信します。サーバ側では、受け取った各パラメータに沿った四則演算を行い、その結果を応答します。クライアント側では受け取った内容を表示します。

演算結果画面
演算結果画面
また、通信中には、Ext.MessageBox.wait() メソッドを使い、ウェイトダイアログを表示するようにしてあります。

ウェイトダイアログ
ウェイトダイアログ
サーバ側からの応答があった場合、responseSuccess() 関数か responseFailure() 関数がコールされます。これらの関数は、Ext.Ajax.request() メソッドのパラメータにコールバック関数として指定します。

パラメータ中の success に設定された関数は、通信が正常に行われた場合にコールバックされます。また failure に設定された関数は、サーバ側から「404」や「500」などの HTTP ステータスが返ってきた場合にコールバックされます。

■this のスコープ
JavaScript でクラスを用いる場合などに問題となるのが this 変数のスコープ問題です。つまり、そのメソッドや関数が、何らかの方法でコールされた場合、その関数内にて参照できる this 変数はどのインスタンスを指し示しているのかというものです。

EXTJS は、この問題に対するアプローチとして、デリゲートを用いています。EXTJS は、JavaScript の Function を拡張し、EXTJS を利用している限り、各関数オブジェクトには createDelegate() メソッドが追加されます。

function myFunc()
{
    alert( this.name );
}
 
var o = { name: 'hogehoge' };
var deleFunc = myFunc.createDelegate( o );
 
myFunc();    //何も表示されない。
deleFunc(); //"hogehoge"と表示される。

上記のように特定の関数に関して、createDelegete() メソッドを使い、デリゲートを作成します。その際にパラメータして、その関数内で this 変数として参照させたいオブジェクトを指定することができます。

EXTJS 内では、このアプローチにて、コールバック関数やイベントハンドラ関数の this スコープに任意のオブジェクトを指定できるように設計されています。

例えば、先ほどご紹介した Ext.Ajax.request() メソッドにおいても、このメソッドに渡す連想配列において scope という項目に任意のオブジェクトを設定することにより、コールバックされる success 項目や failure 項目に指定した関数(ないしメソッド)内にて、this 変数を使ってアクセスすることができるようになります。

■JSON 形式におけるデータの取り扱い
Ajax などによるクライアント−サーバ間の通信では、いろいろなデータ形式が採用されるかと思います。最近では、JavaScript との親和性や取り扱いの容易さから JSON 形式を使うことが多くなっているようです。EXTJS でもこのような流れに沿う形で、JSON 形式データをサポートする関数が用意されています。

Ext.util.JSON クラスを使うことにより、JSON 形式のデータに対してデコード/エンコードを簡単に行えます。このクラスはスタティッククラスのため、そのまま、Ext.util.JSON.encode() といったような形で利用します。

■String クラスの拡張
JavaScript における String クラスに関しても拡張されています。trim() メソッドや format メソッドが追加されているため、以下のような処理を行えます。

var s1 = ' trim test ';
alert( s1.trim() ); //前後の空白が取り除かれ"trim test"と表示される。
 
var name = '山田太郎';
var age = 10;
var s1   = String.format( '{0}は{1}歳です。', name, String(age) );
alert( s1 );        //"山田太郎は10歳です。"と表示される。

■クラス継承
オブジェクト指向なプログラミングを行う際には避けては通れないものとなろうかと思います。EXTJS は、このクラス継承も簡単に行えるように構成されています。

以下の例では、Ext.Panel クラスを継承して新しいクラスを作っています。(このサンプルでは、特段、継承しなければならないわけではありませんが、説明のために敢えて継承を使っています)

<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <title>クラス継承サンプル</title>
 
 <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
 
 <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>
 <script type="text/javascript" src="extjs/ext-all-debug.js"></script>
 
 <script type="text/javascript">
    Ext.BLANK_IMAGE_URL = 'extjs/resources/images/default/s.gif';
   
    Ext.onReady( function()
    {
        //
        //Ext.ux.NewPanel名前空間を作成
        //
        Ext.namespace('Ext.ux.NewPanel');
       
       
        //
        //Ext.Panelを継承して新しいクラスを作成
        //
        Ext.ux.NewPanel = Ext.extend( Ext.Panel, 
        {
            //各プロパティ値の初期設定
            title:       '新しいパネルクラス',
            html:        'これは新しいクラスです。<BR>' +
                         'Ext.extend()メソッドを使って継承しています。',
            width:       300,
            collapsible: true,
           
           
            //initComponent()メソッドのオーバーライド
            initComponent: function()
            {
                this.buttonAlign = 'center';
                this.buttons = [
                    {
                        text:    '送信',
                        scope:   this,
                        handler: function(){
                            Ext.MessageBox.show( {
                                msg:     'データを送信しました。',
                                buttons: Ext.MessageBox.OK,
                                icon:    Ext.MessageBox.INFO
                            } );
                        }
                    }
                ];
               
                //親クラスのinitComponent()メソッドの呼び出し
                Ext.ux.NewPanel.superclass.initComponent.call( this );
            }
        } );
       
       
        var p = new Ext.ux.NewPanel( {
            applyTo: document.body,
        } );
    } );
 </script>
</head>
 
<body>
</body>
</html>


クラスを継承するにはいくつかの方法がありますが、今回は Ext.extend() メソッドにてクラス継承を行っています。コンストラクタの挙動を変更しない場合や、今回のように EXTJS のウィジェットを継承するような場合には、この方法が一番簡単で分かりやすいかと思います。

各プロパティの上書きも行えますし、親クラスメソッドのオーバーライドを行うことも可能です。当然のことながら、プロパティやメソッドの追加も行えます。

また、親クラスのメソッドを呼び出したい場合には、

Ext.ux.NewPanel.superclass.initComponent.call( this );

のように、「継承先クラス .superclass. 呼び出したいメソッド名 .call( this )」のようにすることで、コールすることが可能です。

■その他
EXTJS には、これまでにご紹介した機能以外にも、Ext.Element クラスのように、有用な機能がまだまだ多くあります。API ドキュメントを眺めて頂ければ、ここでご紹介した以上の発見があるかと思います。まずはいろいろと試して頂くことをお勧めします。

記事提供:株式会社環

関連テーマ
プリンター用
記事を転送
この記事をクリップ!
厳選した九州のお野菜とお米をお届け
厳選した九州のお野菜とお米をお届け 野菜の木では、老舗料亭 沙羅の木が厳選した九州のお野菜とお米をお届けします。 毎週、隔週での定期のご購入も可能です。 入会費、年会費、送料、荷造手数料は無料です。
注目のトピックス
Copyright 2012 internet.com K.K. (Japan) All Rights Reserved.