關於應用程序
該程序為儲存秘密數據如銀行賬號和網站登陸證書提供了一個網路介面.還可以是生日和約會追蹤的選擇.這個方法是解釋如何執行銀行和網站證書的存儲.另外兩個功能是留給你自己去完成的.Figure 1 和 Figure 2 提供了一個程序運行時的樣子.
點擊左上方的bank按鈕會出現管理銀行數據的界面(參見Figure 1).點擊已列出的銀行標誌讓用戶可以在選定的銀行上查看和修改具體細節.
Java Web 應用程序上放入YUI Face" src="/d/file/2009/java/79148634fa9e06f9e0739881305fd573.jpg" width=480 twffan="done">
在該頁右側的內嵌控制板顯示了日誌信息.
設計:平衡JavaScript和HTML
用JavaScript 開發一個rich user interface (RUI)出現了一個挑戰那就是到底使用多少HTML和多少JavaScript.任何事情都使用JavaScript和AJAX(從下載UI元素開始)但是沒有HTML是會在伺服器上強加很多要求的.最好的策略就是讓每一個功能或是模塊保證有一頁HTML並且還要有JavaScript頁用於RUI行為,例如動畫,拖放,發送伺服器請求和處理來自UI元素的事件.這個策略就是本文中的應用程序所要使用的.
布局
程序的屏幕區被分成以下四個部分(參加Figure 1)以此來達到理想的功能:
· Action Area: 這個容器包含了按鈕("Bank, " "Web, " "Birthdays," 和 "Appointments"),讓用戶可以選擇管理哪一個條目.
· Listing: 這個容器里有銀行,網路等等的登陸列表,這取決於選擇的內容.
· Work area: 這個容器佔據了頁面的大部分.它顯示了在列表面板上已選擇的條目的完整細節.
· Console: 這個容器顯示狀態信息.
為了獲得理想的布局,HTML標記需要第一個被定義.本程序下載的源代碼中的file/index.html顯示如下:
< body class="yui-skin-sam"> < div id="actionDiv"> < /div> < div id="optionsDiv"> < /div> < div id="workspaceDiv"> < /div> < div id="consoleDiv"> < /div> < /body> |
該部分的style class應該設置為yui-skin-sam,YUI提供的一個默認skin class.YUI組件需要這個類來工作,你可以自定義它來符合程序的要求.例如,以下的定義來自示常式序中的文件/css/main.css,將YUI提供的容器的背景顏色設置為白色:
.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd { background-color: #FFFFFF; } |
· YAHOO.widget.Layout類已初始化並顯示出來.Position屬性通過一個constant來指出哪裡放置容器.Body屬性是引用在HTML標示中定義的div的ID.
· 一個namespace, devx.yuiapp被創建,並且JavaScript class Main被聲明.Main class涉及到所有其他的已創建的JavaScript類並且作為index.html頁的entry point class.
· 在Main class constructor中,init登記為onDOMReady作為調回.當index.html網頁內容可以使用時,init被調用.所有有關index.html網頁的初始化,例如初始化按鈕,為當前上下文下載數據等等,都在init中完成.
· 在init方法中,,各種以Main class 為參考的地方都使用this關鍵字.但是init方法在不同的範圍中被調用原因是它是一個調回方法.為了讓關於Main class的this在調回中,Main class的參考進入第二個參數,而且true進入第三個參數onDOMReady.
· LogReader一個instance被創建.這個為網頁附帶一個控制板來顯示日誌信息.YAHOO.log的調用會使這個控制板顯示很多信息.
· Main class的instance被創建並且分配給一個全程變數main.
JavaScript
Listing 1. JavaScript Class YAHOO.widget.Layout // Define the namespace if(!devx) var devx = {}; if(!devx.yuiapp) devx.yuiapp = {}; // Define the class devx.yuiapp.Main = function() { // Constructor // Setup the layout of this page YAHOO.util.Event.onDOMReady(this.init, this, true); } devx.yuiapp.Main.prototype.init = function () { // Setup the layout this.layout = new YAHOO.widget.Layout({ units: [ { position: 'top', height: 30, body: 'actionDiv', gutter: '1px', resize: true }, { position: 'left', width: 200, body: 'optionsDiv', gutter: '1px', resize: true, scroll: true }, { position: 'center', body: 'workspaceDiv' }, { position: 'bottom', height: 50, body: 'consoleDiv' } ] }); this.layout.render(); this.logReader = new YAHOO.widget.LogReader(); } // Create an instance of the main page var main = new devx.yuiapp.Main(); |
· 當自上而下添加組件或是容器的的時候,使用相對定位(relative positioning)(引用CSS屬性position),而且如果在網頁中從左向右布局組件或是容器時要使用絕對定位(absolute positioning).絕對定位需要你定義屬性left和 top.
· 在初始下載期間下載所有的網頁元素.這個會使添加listeners到UI元素中變得簡單.否則,你需要附上listeners.
· 在網頁中鏈接CSS文件Reset, Base, Grids和Fonts(所有YUI)來為所有的HTML標籤創建默認風格定義.這個確保你的程序在瀏覽器中保持一致的外觀和風格.
功能區
為了添加按鈕到功能區面板,你需要定義HTML標示然後你需要連接YUI widget class Button instance.文件index.html 和 /js/action_bar.js在演示程序中如下:
/index.html value="Birthdays"> value="Appointments"> /js/action_bar.js var hideAllListings = function () { main.banksListing.hide(); main.webListing.hide(); var bdaysListDiv = YAHOO.util.Dom.get('bdaysListDiv'); bdaysListDiv.style.visibility = "hidden"; var apptsListDiv = YAHOO.util.Dom.get('apptsListDiv'); apptsListDiv.style.visibility = "hidden"; } |
var onBankButtonClick = function () { hideAllListings(); hideAllDetails(); // Show banks listing & details main.banksListing.show(); main.bankDetails.show(); } this.banksBtn = new YAHOO.widget.Button("banksBtn"); this.banksBtn.on("click", onBankButtonClick, null, this); |
當用戶點擊Bank按鈕的時候,所有其他的列表和詳細資料被隱藏,並且有關Bank的控制面板出現.其他類的參考通過全程變數main來獲得.
Bank 和Web列表
本文中的演示程序使用模擬的數據(從伺服器上檢索的數據被保存用於下一篇文章).BankListing類顯示存在的銀行名單,並且在選擇一個條目的時候監聽所有的事件.這裡有一個例子來自演示程序中的/js/bank_listing.js文件:
devx.yuiapp.BanksListing = function() { // Constructor } devx.yuiapp.BanksListing.prototype.init = function () { // Test data. This will be fetched from the database var bankData = { banks: [ .... ] }; .... this.list = new devx.yuiapp.List('Bank', bankData.banks, 'banksListDataTableDiv', onBankSelection); this.list.init(); } |
列表條目對於任何實體(Bank,Web等等)都是很常見的,定義一個普通的類devx.yuiapp.List.這個可再度使用的類可以為任何實體類型例示.Listing 2提供了一個例子,在演示程序中的/js/listing.js文件.YUI DataTable是用於展現一個列表的.這裡有一些來自Listing 2的其他要點:
· 專欄定義,數據源定義,而且容器提供數據表傳遞給DataTable constructor..
· 添加Listeners到表格中來突出或不突出行,但用戶將滑鼠放到表格上的時候.
· 自定義格式化被寫入來顯示一個行的一個圖像,而不是URL.
· 調回方法_rowSelectEvent被註冊來被調用,當用戶在列表中選項一個條目的時候.
JavaScript Listing 2. Common Class devx.yuiapp.List devx.yuiapp.List.prototype._initTable = function(){ var imageUrlFormatter = function(elCell, oRecord, oColumn, oData) { elCell.innerHTML = '< img width=155 height=100 src=' oData '>'; } YAHOO.widget.DataTable.Formatter.imageUrlFormatter = imageUrlFormatter; // Define columns var colDefs = [ {key:"id", hidden:true}, {key:"name", hidden:true}, {key:"imageUrl", label: this._title, formatter: YAHOO.widget.DataTable.Formatter.imageUrlFormatter} ]; // Define data source var dataSource = new YAHOO.util.DataSource(this._data); dataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY; dataSource.responseSchema = { fields: ["id", "name", "imageUrl"] }; // Init data table this.table = new YAHOO.widget.DataTable(this._container, colDefs, dataSource); this.table.subscribe("rowMouseoverEvent", this.table.onEventHighlightRow); this.table.subscribe("rowMouseoutEvent", this.table.onEventUnhighlightRow); this.table.subscribe("rowClickEvent", this.table.onEventSelectRow); this.table.subscribe("rowSelectEvent", this._rowSelectEvent, null, this); } |
銀行和網路的詳細資料
當用戶選擇一個條目,列表需要根據選擇下載詳細資料.以下代碼是來自演示程序的/js/bank_listing.js為Bank選項完成這個:
var onBankSelection = function (id) { main.bankDetails.load(id); } |
JavaScript Listing 3. The Class BankDetails devx.yuiapp.BankDetails = function () { // Constructor } devx.yuiapp.BankDetails.prototype.init = function () { this.tabView = new YAHOO.widget.TabView('bankDetailsTabsDiv'); // Register for events from the input text fields this.chkAcNoTxt = new YAHOO.util.Element('chkAcNoTxt'); this.chkAcNoTxt.on('blur', devx.yuiapp.Util.validateNumber); this.chkBalTxt = new YAHOO.util.Element('chkBalTxt'); this.chkBalTxt.on('blur', devx.yuiapp.Util.validateNumber); this.chkAsOfDateTxt = new YAHOO.util.Element('chkAsOfDateTxt'); } devx.yuiapp.BankDetails.prototype.load = function (id) { var bank = this.getBank(id); this.chkAcNoTxt.set('value', bank.checking.ac); this.chkBalTxt.set('value', bank.checking.balance); this.chkAsOfDateTxt.set('value', bank.checking.asOfDate); } devx.yuiapp.BankDetails.prototype.show = function () { var bankDetailsDiv = YAHOO.util.Dom.get('bankDetailsDiv'); bankDetailsDiv.style.visibility = "visible"; } |
為了安裝並配置程序,下載accompanying source files.你將使用JavaScript和HTML 編輯器在一個IDE中編輯它們.對於這個例子,我使用Aptana,一個Eclipse插件,可以支持大量的AJAX庫其中包括YUI.但是,我發現Aptana的自動完成不能為YUI工作.
採用以下步驟為演示程序完成安裝和配置:
1. 解壓accompanying source files到一個文件夾並且在創建Eclipse項目時指出這個文件夾.記住當打開文件的時候要切換視圖到Aptana.為了啟用一個JavaScript類的自動完成(autocompletion),你需要在References 視圖中添加該文件.
2. 創建一個文件夾js-lib/yui那裡是放入index.html的地方,下載YUI library並同時複製build 文件夾.
3. 在FireFox打開index.html文件.我沒有在瀏覽器中測試這個演示程序,如果你選擇使用瀏覽器可能會出現一些錯誤.
你最好保留YUI庫的文件夾結構.否則,一些功能可能不會像期望的那樣工作,特別是那些關於外觀和風格的功能.這是風格定義包含了相對入徑.
調試Firefox 和Firebug
Firebug是一個非常有用的Firefox附加物用來調試豐富的客戶端網路應用程序.Firefox 和Firebug整合在一起具有以下特徵:
· 在HTML標籤中選擇一個div突出載入頁面中的屏幕區域.
· Console 標籤顯示需求的發送和反饋的接收,包括標題信息.在JavaScript執行中的任何錯誤都在這裡被列印出.
· CSS屬性修改在載入頁面中得到快速的反應,大大減少你花費在得到所期望的應用程序的外觀和風格的時間.
· 你可以為一個JavaScript文件設置斷點並查看變數值.
· 你可以在HTML中進一步分析一個選定的元素,通過打開DOM或是Layout標籤.Layout標籤是特別用於計算一個UI元素所佔的像素的.
JavaScript 和YUI Programming的小貼士
當使用JavaScript和 YUI進行web程序開發的時候要記住以下這些建議:
· 要注意callback方法的範圍.如果範圍不正確,this關鍵字提及intended object.YUI庫事件處理類可以讓你傳遞對象到你所設置的範圍中.查看API documentation來看一看對於一個小組件這個是如何完成的
· 有條件的使用伺服器端包括屏幕部分.這個提高了程序的模塊化.演示程序為所有的實體提供了容器.相反,其他實體的UI元素在提供基於一個網頁需求參數上有一定的限制.另外,單獨的網頁可以被定義為一個整體,而且常見的HTML可以包括一個文件標題和頁腳.
· 參照this W3C JavaScript Event Reference學習支持事件的列表.
· 如果你不熟悉你在JavaScript或是一個JavaScript構架中所嘗試做的事情,在每次你做更改之後都測試該程序.如果你測試失敗了,要繼續編寫代碼,當錯誤發生的時候可能很難收回並找到真正的原因.
· 注意如何在Eclipse中使用Local History在特定時間內恢復源文件.也要知道如果事情發生錯誤如何來進行恢復.
下一步驟
有了本文這些內容作鋪墊,你應該很有自信的來試一試JavaScript編程並且使用YUI進行web應用程序開發.通過下載attached source files,可以加強你對這個內容的理解並且嘗試去完成不完整的Birthdays 和Appointments實體.為了這些實體你需要定義必要的HTML標籤,創建列表和詳細的類,並把它們連接到Main class上.
[火星人 ] 在Java Web 應用程序上放入YUI Face已經有645次圍觀