天天看點

ext簡介

無論你是Ext庫的新手,抑或是想了解Ext的人,本篇文章的内容都适合你。本文将簡單地介紹Ext的幾個基本概念,和如何快速地做出一個動态的頁面并運作起來,假設讀者已具備了一些JavaScript經驗和初級了解HTML Dom。

目錄

[收埋]
  • 1 下載下傳Ext
  • 2 開始!
  • 3 Element:Ext的核心
  • 4 擷取多個DOM的節點
  • 5 響應事件
  • 6 使用Widgets
    • 6.1 MessageBox
    • 6.2 Grid
    • 6.3 還有更多的..
  • 7 使用Ajax
    • 7.1 PHP
    • 7.2 ASP.Net
    • 7.3 Cold Fusion

<script type="text/javascript"> if (window.showTocToggle) { var tocShowText = "展開"; var tocHideText = "收埋"; showTocToggle(); } </script>

下載下傳Ext

如果你未曾下載下傳過,那應從這裡下載下傳最新版本的Ext http://extjs.com/downloads 。

針對你的下載下傳需求,有幾個不同的彈性選項。通常地,最穩定的版本,是較多人的選擇。下載下傳解包後,那個example檔案夾便是一個探索Ext的好地方!

開始!

Download Example File
  • IntroToExt.zip

我們将使用Ext,來完成一些JavaScript任務。

Zip檔案包括三個檔案:ExtStart.html, ExtStart.js和ExtStart.css。解包這三個檔案到Ext的安裝目錄中(例如,Ext是在“C:\code\Ext\v1.0”中,那應該在"v1.0"裡面建立目錄“tutorial”。輕按兩下ExtStart.htm,接着你的浏覽器打開啟動頁面,應該會有一條消息告訴你配置已完畢。如果是一個Javascript錯誤,請按照頁面上的指引操作。

在你常用的IDE中或文本編輯器中,打開ExtStart.js看看:

Ext.onReady可能是你接觸的第一個方法。這個方法是指目前DOM加載完畢後,保證頁面内的所有元素能被Script引用(reference)。你可删除alert()那行,加入一些實際用途的代碼試試:

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

Element:Ext的核心

大多數的JavaScript操作都需要先擷取頁面上的某個元素(reference),好讓你來做些實質性的事情。傳統的JavaScript方法,是通過ID擷取Dom節點的:

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

這毫無問題,不過這樣單單傳回一個對象(DOM節點),用起來并不是太實用和友善。為了要用那節點幹點事情,你還将要手工編寫不少的代碼;另外,對于不同類型浏覽器之間的差異,要你處理起來可真頭大了。

進入Ext.element 對象。元素(element)的的确确是Ext的心髒地帶,--無論是通路元素(elements)還是完成一些其他動作,都要涉及它。Element的 API是整個Ext庫的基礎,如果你時間不多,隻是想了解Ext中的一兩個類的話,Element一定是首選!

由ID擷取一個Ext Element如下(首頁ExtStart.htm包含一個div,ID名字為“myDiv”,然後,在ExtStart.js中加入下列語句):

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

再回頭看看Element對象,發現什麼有趣的東東呢?

  • Element包含了常見的DOM方法和屬性,提供一個快捷的、統一的、跨浏覽器的接口(若使用Element.dom的話,就可以直接通路底層DOM的節點。);
  • Element.get()方法内置緩存處理(Cache),多次通路同一對象效率上有極大優勢;
  • 内置常用的DOM節點的動作,并且是跨浏覽器的定位的位置、大小、動畫、拖放等等(add/remove CSS classes, add/remove event handlers, positioning, sizing, animation, drag/drop)。

這意味着你可用少量的代碼來做各種各樣的事情,這裡僅僅是一個簡單的例子(完整的清單在ElementAPI中)。

繼續在ExtStart.js中,在剛才我們擷取好myDiv的位置中加入:

myDiv.highlight();      //黃色高亮顯示然後漸退
myDiv.addClass('red');  // 添加自定義CSS類 (在ExtStart.css定義)
myDiv.center();         //在視圖中将元素居中
myDiv.setOpacity(.25);  // 使元素半透明
           

擷取多個DOM的節點

通常情況下,想擷取多個DOM的節點,難以依靠ID的方式來擷取。有可能因為沒設定ID,或者你不知道ID,又或者直接用ID方式引用有太多元素了。這種情況下,你就會不用ID來作為擷取元素的依據,可能會用屬性(attribute)或CSS Classname代替。基于以上的原因,Ext引入了一個功能異常強大的Dom Selector庫,叫做DomQuery。

DomQuery可作為單獨的庫使用,但常用于Ext,你可以在上下文環境中(Context)擷取多個元素,然後通過Element接口調用。令人欣喜的是,Element對象本身便有Element.selcect的方法來實作查詢,即内部調用DomQuery選取元素。這個簡單的例子中, ExtStart.htm包含若幹段落(

标簽),沒有一個是有ID的,而你想輕松地通過一次操作馬上擷取每一段,全體執行它們的動作,可以這樣做:

// 每段高亮顯示
Ext.select('p').highlight();
           

DomQuery的選取參數是一段較長的數組,其中包括W3C CSS3 Dom選取器、基本XPatch、HTML屬性和更多,請參閱DomQuery API文檔以了解這功能強大的庫個中細節。

響應事件

到這範例為止,我們所寫的代碼都是放在onReady中,即當頁面加載後總會立即執行,功能較單一——這樣的話,你便知道,如何響應某個動作或事件來執行你希望做的事情,做法是,先配置設定一個function,再定義一個event handler事件處理器來響應。我們由這個簡單的範例開始,打開ExtStart.js,編輯下列的代碼:

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

加載好頁面,代碼依然會執行,不過差別是,包含alert()的function是已定義好的,但它不會立即地被執行,是配置設定到按鈕的單擊事件中。用淺顯的文字解釋,就是:擷取ID為'myDottom'元素的引用,監聽任何發生這個元素上被單擊的情況,并配置設定一個function,以準備任何單擊元素的情況。

正路來說,Element.select也能做同樣的事情,即作用在擷取一組元素上。下一例中,示範了頁面中的某一段落被單擊後,便有彈出視窗:

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

這兩個例子中,事件處理的function均是簡單幾句,沒有函數的名稱,這種類型函數稱為“匿名函數(anonymous function)”,即是沒有名的的函數。你也可以配置設定一個有名字的event handler,這對于代碼的重用或多個事件很有用。下一例等效于上一例:

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

到目前為止,我們已經知道如何執行某個動作。但當事件觸發時,我們如何得知這個event handler執行時是作用在哪一個特定的元素上呢?要明确這一點非常簡單,Element.on方法傳入到even handler的function中(我們這裡先讨論第一個參數,不過你應該浏覽API文檔以了解even handler更多的細節)。在我們之前的例子中,function是忽略這些參數的,到這裡可有少許的改變,——我們在功能上提供了更深層次的控制。必須先說明的是,這實際上是Ext的事件對象(event object),一個跨浏覽器和擁有更多控制的事件的對象。例如,可以用下列的語句,得到這個事件響應所在的DOM節點:

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

注意得到的e.target是DOM節點,是以我們首先将其轉換成為EXT的Elemnet元素,然後執行欲完成的事件,這個例子中,我們看見段落是高亮顯示的。

使用Widgets

(Widget原意為“小器件”,現指頁面中UI控件)
      

除了我們已經讨論過的核心JavaScript庫,目前的Ext亦包括了一系列的最前端的JavaScirptUI元件庫。文本以一個常用的widget為例子,作簡單的介紹。

MessageBox

比起略為沉悶的“HelloWolrd”消息視窗,我們做少許變化,前面我們寫的代碼是,單擊某個段落便會高亮顯示,現在是單擊段落,在消息視窗中顯示段落内容出來。

在上面的paragraphClicked的function中,将這行代碼:

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
});
           

這裡有些新的概念需要讨論一下。在第一行中我們建立了一個局部變量(Local Variable)來儲存某個元素的引用,即被單擊的那個DOM節點(本例中,DOM節點指的是段落paragrah,事因我們已經定義該事件與< p>标簽發生關聯的了)。為什麼要這樣做呢?嗯...觀察上面的代碼,我們需要引用同一進制素來高亮顯示,在MessageBox中也是引用同一進制素作為參數使用。

一般來說,多次重複使用同一值(Value)或對象,是一個不好的方式,是以,作為一個具備良好OO思維的開發者,應該是将其配置設定到一個局部變量中,反複使用這變量!

現在,為了我們接下來闡述新概念的示範,請觀察MessageBox的調用。乍一看,這像一連串的參數傳入到方法中,但仔細看,這是一個非常特别的文法。實際上,傳入到MessageBox.show的隻有一個參數:一個Object literal,包含一組屬性和屬性值。在Javascript中,Object Literal是動态的,你可在任何時候用{和}建立一個典型的對象(object)。其中的字元由一系列的name/value組成的屬性,屬性的格式是[property name]:[property value]。在整個Ext中,你将會經常遇到這種文法,是以你應該馬上消化并吸收這個知識點!

使用Object Literal的原因是什麼呢?主要的原因是“可伸縮性(flexibility)”的考慮",随時可新增、删除屬性,亦可不管順序地插入。而方法不需要改變。這也是多個參數的情況下,為最終開發者帶來不少的友善(本例中的MessageBox.show())。例如,我們說這兒的foo.action方法,有四個參數,而隻有一個是你必須傳入的。本例中,你想像中的代碼可能會是這樣的foo.action(null, null, null, 'hello').,若果那方法用Object Literal來寫,卻是這樣, foo.action({ param4: 'hello' }),這更易用和易讀。

Grid

Grid是Ext中人們最想先睹為快的和最為流行Widgets之一。好,讓我們看看怎麼輕松地建立一個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 ds = new Ext.data.Store({
		proxy: new Ext.data.MemoryProxy(myData),
		reader: new Ext.data.ArrayReader({id: 0}, [
			{name: 'company'},
			{name: 'price', type: 'float'},
			{name: 'change', type: 'float'},
			{name: 'pctChange', type: 'float'},
			{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
	])
	});
	ds.load();
 
	var colModel = new Ext.grid.ColumnModel([
		{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'}
	]);
 
	var grid = new Ext.grid.Grid('grid-example', {ds: ds, cm: colModel});
		grid.render();
		grid.getSelectionModel().selectFirstRow();
	});
           

這看上去很複雜,但實際上加起來,隻有七行代碼。第一行建立數組并作為資料源。實際案例中,你很可能從資料庫、或者WebService那裡得到動态的資料。接着,我們建立并加載data store, data store将會告訴Ext的底層庫接手處理和格式化這些資料。接着,我們定義一個column模型,用來輕松地調配Grid的每一列參數。最後我們生成這個Grid,傳入data store和column模型兩個對象,進行渲染并選好第一行。不是太困難吧?如果一切順利,完成之後你會看到像這樣的:

ext簡介

當然,你可能未掌握這段代碼的某些細節(像MemoryProxy究竟是什麼?)但先不要緊,這個例子的目的是告訴你,用少量的代碼,建立一個富界面的多功能的UI元件而已——這是完全可能的,隻要讀者您有興趣學習。這兒有許多學習Grid的資源。Ext Grid教程、交叉Gird示範和Grid API文檔。

還有更多的..

這隻是冰山一角。還有一打的UI Widgets可以供調用,如 layouts, tabs, menus, toolbars, dialogs, tree view等等。請參閱API文檔中範例示範。

使用Ajax

在弄好一些頁面後,你已經懂得在頁面和腳本之間的互動原理(interact)。接下來,你應該掌握的是,怎樣與遠端伺服器(remote server)交換資料,常見的是從資料庫加載資料(load)或是儲存資料(save)到資料庫中。通過JavaScript異步無重新整理交換資料的這種方式,就是所謂的Ajax。Ext内建卓越的Ajax支援,例如,一個普遍的使用者操作就是,異步發送一些東西到伺服器,然後,UI元素根據回應(Response)作出更新。這是一個包含text input的表單,一個div用于顯示消息(注意,你可以在ExtStart.html中加入下列代碼,但這必須要通路伺服器):

<div id="msg" style="visibility: hidden"></div> 

Name: <input type="text" id="name" /><br /> 

<input type="button" id="oKButton" value="OK" />      

接着,我們加入這些處理交換資料的JavaScript代碼到檔案ExtStart.js中(用下面的代碼覆寫):

Ext.onReady(function(){
	Ext.get('oKButton').on('click', function(){
		var msg = Ext.get('msg');
			msg.load({
			url: [server url], //換成你的URL
			params: 'name=' + Ext.get('name').dom.value,
			text: 'Updating...'
 
		});
		msg.show();
	});
});
           

這種模式看起來已經比較熟悉了吧!先擷取按鈕元素,加入單擊事件的監聽。在事件處理器中(event handler),我們使用一個負責處理Ajax請求、接受響應(Response)和更新另一個元素的Ext内建類,稱作UpdateManager。 UpdateManager可以直接使用,或者和我們現在的做法一樣,通過Element的load方法來引用(本例中該元素是id為“msg“的 div)。當使用Element.load方法,請求(request)會在加工處理後發送,等待伺服器的響應(Response),來自動替換元素的 innerHTML。簡單傳入伺服器url位址,加上字元串參數,便可以處理這個請求(本例中,參數值來自“name”元素的value),而text值是請求發送時提示的文本,完畢後顯示那個msg的div(因為開始時預設隐藏)。當然,和大多數Ext元件一樣,UpdateManager有許多的參數可選,不同的Ajax請求有不同的方案。而這裡僅示範最簡單的那種。

PHP

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

ASP.Net

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

Cold Fusion <cfif></cfif>

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

最後一個關于Ajax隐晦的地方就是,伺服器實際處理請求和傳回(Resposne)是具體過程。這個過程會是一個服務端頁面,一個Servlet,一個 Http排程過程,一個WebService,甚至是Perl或CGI腳本,即不指定一個伺服器都可以處理的http請求。讓人無法預料的是,伺服器傳回什麼是伺服器的事情,無法給一個标準的例子來覆寫闡述所有的可能性。(這段代碼輸出剛才我們傳入'name'的那個值到用戶端,即發送什麼,傳回什麼)。

使用Ajax的真正挑戰,是需要進行适當的手工編碼,并相應格式化為服務端可用接受的資料結構。有幾種格式供人們選擇(最常用為JSON/XML)。正因 Ext是一種與伺服器語言免依賴的機制,使得其它特定語言的庫亦可用于Ext處理Ajax服務。隻要頁面接受到結果是EXT能處理的資料格式,Ext絕不會幹涉伺服器其他的事情!要全面讨論這個問題,已超出本文的範圍。推薦正在Ajax環境下開發的您,繼續深入閱讀Ext Ajax教程。

繼續閱讀