Ext JS - Learning Center

Tutorial:Introduction to Ext 2.0 (Japanese)

From Learn About the Ext JavaScript Library

Jump to: navigation, search
Summary: Ext ライブラリの概要と、よくある作業の流れの紹介になります。新規のユーザーは、ここから始めると良いでしょう。
Author: Itou Akihiro
Published: 2008年1月28日
Ext Version: 2.0
Languages: en.png English cn.png Chinese jp.png Japanese

kr.png Korean

このチュートリアルはExt version 2.0用のものです。 1.xのIntroduction to Ext はこちらになります。

Extを初めて使う方、もっと知りたい方、ようこそこのTutorialへ。ここでは、Extの基本的なコンセプトと動的ページの作成・実行方法について述べています。読者として想定しているのは、javascriptの経験があり、HTMLドキュメントオブジェクトモデル(DOM)に関する基本的な理解がある方です。

Extをダウンロードする

まだExtをダウンロードしていないのでしたら、まずは以下のサイトから最新版をダウンロードしてください:http://extjs.com/download

色々と有りますが、おそらく必要とされるのは、最新の安定製品版(the most current stable production version)でしょう。ダウンロードして解凍し、examplesディレクトリ内をいろいろと眺めてみるのも良いでしょう。

さぁはじめましょう

Download Example File

javascriptを使ってなにかしらやりたい人に共通ないくつかの作業や、Extを使っていく方法について見ていきましょう。まずは、IntroToExt2.zipをダウンロードしてみてください。このファイルは我々がExtのコードを試すページを作成する時に使ったりするものです。

このzipファイルは、ExtStart.htmlExtStart.jsExtStart.cssajax-example.php の4つのファイル含みます。

  • これらファイルを、Extをインストールしたディレクトリ直下のディレクトリに解凍して置いてください。 Extが "C:\code\ext-2.0" にあるのならば、新しいディレクトリ "tutorial" を "ext-2.0" 内に作成し "C:\code\ext-2.0\tutorial\" としてください。
  • ExtStart.html をダブルクリックすればデフォルトのブラウザが起動し、うまくいっていることを告げるメッセージが出てくるはずです。 javascriptのエラーが出た場合は、メッセージに従ってなんとか動くようにしてください。

それでは、 ExtStart.js の内部を見てみましょう。 IDEなりテキストエディターなりで開いてみてください。

Ext.onReady(function() {
	alert("Congratulations!  You have Ext configured correctly!");
});

Ext.onReadyは、これからあなたがページを作成する度に出会うことになるメソッドとなるでしょう。このメソッドは、DOMが完全に読みこまれた後に自動的に呼び出されるものです。 Ext.onReadyが呼び出された時、参照したいすべてのページ要素が利用できることが保証されています。さてここまで良いでしょうか? それではこのalert()行を消して、実際に役に立つコードを書き足していくことにしましょう。

Element: Extの要

おおよそjavascriptを使う全てのケースで、ページの要素を参照し利用することになると思います。通常Javasriptでは、DOMノードをIDから取得するには以下のようになります。

var myDiv = document.getElementById('myDiv');

当然ながら動きますね。ですが返ってきたオブジェクト(DOMノード)は、あまり使い勝手の良いものではありません。このノードに何かしようとすると、あれこれコードを書くことになります。加えて、ノード操作に関するブラウザごとの微妙な違いを全て吸収するようなコードを書く必要もあります。勘弁して欲しいところですよね。

そこでExt.Elementオブジェクトです。このElementが、Extの要なのです。 ElementのAPIは、Extライブラリのキソであり、もしExtを深く理解しようとしてなにかひとつのクラスを時間をかけて勉強するというのならば、間違いなくこのElementクラスなのです。

ID指定でElemenetオブジェクトを取り出すコードは以下のようになります。 ExtStart.htmlは、 "myDiv" をidとするdivノードを含むので、このコードをExtStart.jsに書き加えてください。

Ext.onReady(function() {
	var myDiv = Ext.get('myDiv');
});

これでElementオブジェクトが取得できました。で何が嬉しいのでしょうか?

  • Elementオプジェクトは、必要と思われる主要なDOMメソッドとプロパティをラップしており、便利で、一貫性があり、ブラウザ互換なDOMインターフェースを提供します(そして、Element.domで直接アクセスも可能です)
  • Element.get()メソッドは、内部キャッシュを提供し、同一オブジェクトに対する二回目移行のアクセスはとても速い
  • DOMノードに対する多くの共通の操作が、Elemenentのメソッドとして組みこまれている(CSSのクラスの追加・削除、イベントハンドラの追加・削除、位置、サイズ、アニメーション、ドラッグ&ドロップ等々)

もろもろのことが、非常に少ないコードで実現できることになります。ここではいくつかの簡単な例を扱っています(Element の API ドキュメントには、できることの全てのリストがあります)。それではExtStart.jsの'myDiv' Elementオブジェクトを取得した行の後に以下のものを加えてみましょう。

myDiv.highlight();      // 要素の背景が黄色にハイライトされ、もとの色に戻っていきます
myDiv.addClass('red');  // カスタムCSSクラスを追加します(ExtStart.cssで定義してあります)
myDiv.center();         // 要素をセンタリングします
myDiv.setOpacity(.25);  // 要素を部分透過にします

DOM ノードを取り出す

DOMのノードをIDから取り出すことが、できなかったり難しかったりすることがしばしばあります。IDがセットされていないとか、知らないとか、要素が多過ぎてでIDで見にいくのが現実的でなかったり。ID以外、たとえば属性やCSSクラス名でノードを取り出したいこともあるでしょう。このような理由で、Extは DomQuery と呼ばれる大変強力なDOM セレクタ ライブラリを持っています。

DomQuery は単独のライブラリとして使うこともできますが、Extと一緒に使うことで、Elementオブジェクトを取り出すことができ、Elementのインターフェースを使って操作することが可能となります。幸せなことに、Elementオブジェクト自身がselectメソッド持ってて要素を取り出すことできます。このメソッドは内部的にDomQuery使っています。で、簡単な例になりますが、ExtStart.htmlは、いくつかの<p>タグがあり、idがついていません。その全ての要素を取りだしたり操作したりしたければ、こんな感じで可能になります。

// Highlights every paragraph
Ext.select('p').highlight();

この例を見れば判るように、Element.selectはとてもお手軽です。 Element.selectは CompositeElement を返し、CompositeElementが個々のElementへのアクセスを提供します。こうしてloopして個別アクセスすること無しに、全てのElementのインスタンスを簡単に操作できることになります。

DomQueryは、W3C CSS3 DOMセレクタやXPathや、HTML属性やなどなど多くのものをサポートしています。その強力なライブラリの詳細に関しては、DomQuery API ドキュメント を見てください。

イベント応答

ここまでのサンプルでは、全てのコードがonReady関数の中にあり、ページがロードされた後に実行されていました。これだけだとちょっと何もできませんね。普通扱いたいアクションやらイベントやらで実行するコード書きますよね。で、イベントハンドラを書く訳です。

それではやってみましょう。 ExtStart.jsを開いて、以下のコードを打ち込んでください。

Ext.onReady(function() {
    Ext.get('myButton').on('click', function(){
        alert("You clicked the button");
    });
});

このコードも今までのもと同様に、ページのロード時に動作しますが、重要な違いがあります。 alert関数を含む関数が定義されているものの、ロード時には実行されていません。 button clickイベントの "イベントハンドラ" として登録されているだけです。この部分を読み下すと、「idが'myButton'のElementへの参照を取得して、誰かがクリックした時に呼ばれる関数を登録する」となります。

当然のことながら、Element.selectでも同様のことができますが、selectされた要素の全部に適用されてしまいます。例えば、いずれかの <p> 要素がクリックされた時にメッセージを表示するには以下のように記述します。

Ext.onReady(function() {
	Ext.select('p').on('click', function() {
		alert("You clicked a paragraph");
	});
});

ここまでの2つの例では、イベントハンドラは単にインラインで定義されており、関数名を持ちませんでした。このような関数は名前を持たないことから、"匿名関数(anonymous function)" と呼ばれています。イベントはハンドラに名前を付けることは可能であり、その関数を再利用するような場合や複数のイベントに紐付けるようなケースで特に有効です。以下の例では、コードは機能的に先程の例と同値です。

Ext.onReady(function() {
    var paragraphClicked = function() {
      alert("You clicked a paragraph");
    }
    Ext.select('p').on('click', paragraphClicked);
});

ここまで、イベントが発生した際の動作を見てきましたが、どうやって正確にどのElementがそのイベントを投げているかを、知ることができるのでしょう? 実は簡単です。 Element.on メソッドが、3つの役に立つパラメータをイベントハンドラに渡します(ここでは1つしか使っていませんが、APIドキュメントを見て詳細を探してみても良いでしょう)。これまでのサンプルでは、これらのパラメータを無視してきました。が、ちょこっと変更すれば、さらなる便利さを手にすることができます。第一パラメータが(これが一番大事)、発生したイベントです。これは、 Ext.EventObject で、ブラウザ間の差異を吸収したものであり、標準的なブラウザが提供するよりもずっと多くの情報を含みます。例えば、イベントのターゲットとなるDOMノードは以下のように追加するだけで簡単に参照することができます。

Ext.onReady(function() {
	var paragraphClicked = function(e) {
		Ext.get(e.target).highlight();
	}
	Ext.select('p').on('click', paragraphClicked);
});

targetがDOMノードです。ですので、最初にそのElementを取得し、それからそこでやりたいことをやってます。 この例の場合では、クリックした<p>要素をハイライトします。

Widget を使う

ここまで扱ってきたcore javascriptライブラリに加えて、Extには大変リッチなUI widget群があります。このチュートリアルでその全てを語るのは難しいのですが、とりあえずいくつかよく使うwidgetをとりあげます。で、どれほど簡単か実感してください。

MessageBox

ありがちな "Hello Wolrd" なメッセージボックスではなく、少し趣向を凝らしてみましょう。前の章でクリックしたパラグラフをハイライトするコードを書きました。それを修正して、クリックしたパラグラフをメッセージボックスで表示しましょう。 paragraphClicked関数の中で、以下の部分を置きかえてみてください。

Ext.get(e.target).highlight();

この部分を以下のように置き換えます。

var paragraph = Ext.get(e.target);
paragraph.highlight();
 
Ext.MessageBox.show({
	title: 'Paragraph Clicked',
	msg: paragraph.dom.innerHTML,
	width:400,
	buttons: Ext.MessageBox.OK,
	animEl: paragraph
});

いくつかの着目すべき新しいコンセプトがここにはあります。最初の行で、paragraphというローカル変数を用意し、これでクリックしたDOMノードのElementを保持します(このケースでは、clickイベントがパラグラフにしかアサインされていないことを知ってますので)。どうしてこんなことをしているのでしょう? もう少し先を見てください、ハイライトさせるのにElementが必要になっています。そして、そのElementをMessageBoxのパラメータの中でちらほら使ってますよね。一般的に、同じ値やら参照やらを引き出すのに同じ関数を何度も使うのは良いことではありません。なので、ローカル変数に入れて、使いまわす訳です。頑張って良いobject-oriented デベロッパーになりましょう。

次にMessageBoxの呼びだしについて。一見すると、これは単にメソッドにいくつかのパラメータを渡してるだけにも見えますが、よく見てみると、きわめて独特の処理をしています。実はこのケースで実際にMessageBox関数に渡されている引数は1つだけです。それは属性と値の集合を含むオブジェクトリテラルです。 JavaScriptでは、オブジェクトリテラルは{}で囲まれた名前/値の属性のリストで使用した時に動的に生成されるオブジェクトで、属性は[名前]:[属性]の形で記述されます。 Extではこの手の表現を嫌というほど使うことになりますので、頑張って慣れておいてください!

何故オブジェクトリテラルを使うのでしょうか? その主な理由は柔軟性です。 メソッドのシグネチャ(メソッドのパラメータの数とそれぞれの型)を変更せずに、object literalに新しい属性を追加したり削除したりできます。また、多くのオプショナルのパラメータとともにメソッドを使う時に、大変見通しが良いのです(MessageBox.showみたく)。例えば、foo.actionというメソッドがあるとしましょう。このメソッドは4つのオプショナルのパラメータを持ち、必須はそのうちの1つとします。この場合、foo.action(null,null,null,'hello')みたくなることでしょう。しかしこのメソッドが引数としてひとつのオブジェクトリテラルならば、foo.action({ param4: 'hello' })となります。ずっと使いやすくて読みやすいですね。

Grid

gridはExtを代表するwidgetであり、見てみたいものの筆頭でしょう。ここでは、基本的なgridを動かしてみて、その簡単さを堪能することにしましょう。 ExtStart.jsのコードを以下のように置き換えてください。

Ext.onReady(function() {
	var myData = [
		['Apple',29.89,0.24,0.81,'9/1 12:00am'],
		['Ext',83.81,0.28,0.34,'9/12 12:00am'],
		['Google',71.72,0.02,0.03,'10/1 12:00am'],
		['Microsoft',52.55,0.01,0.02,'7/4 12:00am'],
		['Yahoo!',29.01,0.42,1.47,'5/22 12:00am']
	];
 
	var myReader = new Ext.data.ArrayReader({}, [
		{name: 'company'},
		{name: 'price', type: 'float'},
		{name: 'change', type: 'float'},
		{name: 'pctChange', type: 'float'},
		{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
	]);
 
	var grid = new Ext.grid.GridPanel({
		store: new Ext.data.Store({
			data: myData,
			reader: myReader
		}),
		columns: [
			{header: 'Company', width: 120, sortable: true, dataIndex: 'company'},
			{header: 'Price', width: 90, sortable: true, dataIndex: 'price'},
			{header: 'Change', width: 90, sortable: true, dataIndex: 'change'},
			{header: '% Change', width: 90, sortable: true, dataIndex: 'pctChange'},
			{header: 'Last Updated', width: 120, sortable: true, 
				renderer: Ext.util.Format.dateRenderer('m/d/Y'), 
	                        dataIndex: 'lastChange'}
		],
		viewConfig: {
			forceFit: true
		},
		renderTo: 'content',
		title: 'My First Grid',
		width: 500,
		frame: true
	});
 
	grid.getSelectionModel().selectFirstRow();
});

いろいろと書いてはありますが、全部で4つの文しかありません(テストデータを数えないと3つです)!

  • 最初の行で、gridに表示するテストデータの配列を作ります。実際のプロジェクトでは、おそらくデータベースやWebサービスなどの動的なソースからデータを引き出すことになるでしょう。
  • 次に、データリーダを作成します。これはデータを解釈し、変換して行に変換します。種々のデータタイプに合わせていくつかのReaderクラスが用意されています。
  • そして、以下を含むgridウィジェットを作成し、全ての設定値を渡します。
    • 準備したテストデータとリーダで設定された新しいデータストア
    • 列の設定に基づく列モデル
    • gridへの追加オプション
  • 最後に、SelectionModelを通してその最初の行をハイライトさせます。

簡単ですよね? これだけ書けば下の画像のようなものが仕上がるはずです。

Image:IntroToExt2_grid.gif

もちろん今の段階では詳細は理解できないかもしれません。この例を上げた意図は、とってもリッチで複雑なユーザーインターフェースのコンポーネントを少ないコードで実現できることを見てもらうことにあります。まだまだ学ぶべきことは山程あります。しかし山程あるドキュメントやサンプルがgridを学習する助けになります。デモはこちらGridPanel API ドキュメントはこちら になります。

さらにさらに...

ここまで見てきたものは氷山の一角に過ぎません。 Extには文字通り数ダースに及ぶ多くのUI widgetがあります。自動ページレイアウト、タブ、メニュー、ツールバー、ダイアログ、ツリーetcetc。こちらのサンプル をいろいろ試してみてください。いろいろとできることが見えてくると思います。

Ajax を使う

ページを作成してjavascriptでインタラクティブにやる方法を知ると、次はおそらくサーバ上のデータベースを扱いたくなってくるでしょう。 javascriptを使ってページをリロードすることなく非同期にこれを行なうのが、 Ajax の名で知られているものです。 Extは、洗練されたAjaxのサポートも組みこまれています。例をあげましょう。ユーザーとの対話を扱うときによくあることで、サーバとの非同期通信により、操作に対してUI要素を更新するということがあると思います。以下が、そういったケースでの、inputフィールドとボタンとメッセージを表示するためのdiv要素とからなる簡単なHTMLフォームになります (このコードをExtStart.htmlに加えることはできますが、下のサーバ側のコードを実行するためのwebサーバのアクセスが必要になります)。

<div>
    Name: <input type="text" id="name" />
    <input type="button" id="okButton" value="OK" />
</div>
<div id="msg"></div>

次に、データを取りだしたりサーバに渡したりするのに必要なjavascriptのコードを追加します。 ExtStart.jsのコードを以下に置き換えてください。

Ext.onReady(function(){
	Ext.get('okButton').on('click', function(){
		var msg = Ext.get('msg');
		msg.load({
			url: 'ajax-example.php', // <-- change if necessary
			params: 'name=' + Ext.get('name').dom.value,
			text: 'Updating...'
		});
		msg.show();
	});
});

Note: この例はweb server上でしか動きません。 ブラウザ上のURLが file:// ではなく http:// で始まるところでないと、Ajaxの処理は動きません。localhostで動かすのは構いませんが、http経由でなければいけません。

 さてここまでやってこられたならば、ここらへんには慣れてきている頃ではないかと思います。このコードは、okButton の入力をElementオブジェクトで覆っていて、そのボタンを押したときの処理を行なう匿名関数をあてています。 clickのハンドラは、 Updater と呼ばれるExtに組みこまれている特別なクラスを使っていまして、このクラスはAjaxリクエストを送ってて、レスポンスを受けてElementをさくっと更新しています。 Updaterは更新したい要素(この場合msg div)を通じてアクセスすることでダイレクトに使うことができます。 Element.loadが使用された時に、サーバーのレスポンスは自動的に要素のinnerHTMLを置き替えます。単にURLのサーバーベースのプロセスに渡すことで、クエリストリングのパラメータは処理されて要素のinnerHTMLの中にテキストとして表示されます。で、msg divが表示され(最初はhidden)ます。もちろん、Extでよくある話なのですが、Updaterには大量のオプションがあり、いくつかのAjaxリクエストを扱う方法がケース毎に用意されてはいますが(より詳しい説明は Ext.Ajax を見てください)、とにもかくにも、簡単にAjaxが動くことを見てもらうことができたのではないでしょうか。

Ajaxについての最後の難関は、webサーバ上で、正確にリクエストを処理しページに対して応答することです。これは、server pageやらservletやらHTTPハンドラやらWebサービスやらPerlやらCGIスクリプトやらだったりしますが、Webサーバ側の処理でHTTPリクエストにを処理するもろもろのことです。不幸なことに、あまりに多くのケースがあり全てをカバーする一般的な例を提示することはできません。ここでは、よく使われてるであろうケースでのいくつかの例を載せます。これが役に立てば幸いです。これらのコードは'name'が何であれ「From Server」をその先頭に付けて返すだけのものです。 PHPのサンプルは、最初にダウンロードしたajax-example.phpに含まれているものですが、選んだコードに置きかえてください。

Plain PHP

<?php if(isset($_POST['name'])) {
		echo 'From Server: '.$_POST['name'];
	}
?>

CakePHP

<?php if(isset($this->data['name'])) {
		$this->flash('From Server: '.$this->data['name']);
	}
?>

Django

from django.http import HttpResponse
 
def ajax_request(request):
    return HttpResponse('From Server: %s' % request.POST.get('name', 'nada'))

Perl

#!/usr/bin/perl
use strict;
use warnings;
use CGI;
 
my $Query = new CGI;
 
print $Query->header();
print "Hello from : ".$Query->param('name');
 
exit;

ASP.Net

protected void Page_Load(object sender, EventArgs e)
{
	if (Request.Form["name"] != null)
	{
		Response.Write("From Server: " + Request.Form["name"]);
		Response.End();
	}
}

ColdFusion

<cfif StructKeyExists(form, "name")>
    <cfoutput>From Server: #form.name#</cfoutput>
</cfif>

    or using ColdFusion Scripting (cfscript)

if (StructKeyExists(form, "name")) {
        writeoutput("From Server : " & form.name);
        }

JSTL (JSP)

From Server: ${param.name}

Ruby on Rails

render :text => "From Server: #{params[name]}"

実際にAjaxを扱う場合には、適切な処理と構造化されたデータフォーマットを扱う様々なコードを必要とします。いくつかの広く使われているフォーマットがあります(JSONかXMLが多いでしょう)。また、Ajaxを処理するためのそれぞれの言語特有のライブラリが山程あり、Extはサーバ側の言語に依存しないため、それらの言語とExtとの相性もいいことでしょう。適切なフォーマットでページに送られてくる限り、Extはサーバで何があろうと気にしません。更なるサーバー側のフレームワークやツールに関する情報については、我々のプラットホームごとのリソースのリストを見てください。

次は何をすれば良いの?

ここまで来れば、Extの雰囲気は掴めてきたと思います。まだまだ多くの有用なリソースがExtにはあり、 これらがあなたを次なるレベルへ導いてくれることでしょう。

  • This page was last modified 14:58, 17 February 2008.
  • This page has been accessed 17,833 times.