Bootstrap是一個利用Convention就幫忙做掉很多事情的一個CSS Framework,讓程式設計師可以很簡單的就可以做出一個很漂亮的UI。

雖然稱為CSS Framework,但其實後端是利用jQuery當作Base幫你處理掉很多事情,也有開放一些介面讓你可以Customize一些功能,可以定義為簡單好看又好用的Framework。

由於Bootstrap的基礎功能不多,因此外界開發了許多建立在Boostrap上的plugin,就像是jQuery有許多plugin依樣,而Bootstrap Table就是其中的一個。

Bootstrap Table

 一、資源安裝

為了要執行Bootstrap Table你必須要先Includer幾個library
1. jquery.js  
    http://jquery.com/

2. bootstrap.js , bootstrap.css
    http://getbootstrap.com/ 下載之後解壓縮會找到這兩個檔案

3. 安裝glyphicons
    在bootstrap.zip裡面有一個font的folder,glyphicon所有的圖為了要能縮放,都做成了字型!所以要安裝字型必須要去改bootstrap.css的url的位置
      - 將font整個folder放進去你的server的folder中
      - 打開bootstrap.css搜尋glyphicon,更改內部的url的位置

4. boostrap-table.js, bootstrap-table.css 
    http://bootstrap-table.wenzhixin.net.cn/

二、Bootstrap Table

你的程式有參考上列的資源後,基本上不需要寫任何的JS跟CSS就可以讓你的Table變得很漂亮了,我不會詳細介紹每個細節,因為Bootstrap Table已經有很清楚的範例,我在這只會介紹幾個重要的key point以及document沒有提到的

Example : http://bootstrap-table.wenzhixin.net.cn/examples/ ,  http://wenzhixin.net.cn/p/bootstrap-table/docs/examples.html
Document : http://bootstrap-table.wenzhixin.net.cn/documentation/

怎麼看Doc : 打開上面的Document網頁,Name是在用javascript的時候用的,而Attribute則是當你要加在HTML tag的屬性時使用

1. Basic Table

只要在你的<table>裡面加上屬性  data-toggle="table",恭喜你,你的table已經變成Bootstrap的好看介面了,更棒的是很多好用的功能,也只需要另外加在<table>即可

    * data-classes : 放class的地方,預設是"table table-hover" 是bootstrap table的格式, 且hover會有效果,如果加上"table-condensed" 則會出現比較小的行距
    * data-striped: 要不要在Row之間畫線

2. Load Data的方式

提供三種可以將資料匯入的方式

- From HTML : HTML內本來就有<table>的所有資料,只要加上屬性data-toggle="table"就可以了
- From data : 如果你的資料是在javascript內,那麼你必須要做
     * <th>要加上一個屬性 data-field="fieldNameA"
     * 在JS中你的物件的key必須match這個name,並用陣列包起來
     * 在JS中執行 $('#myTable').bootstrapTable({data : mydata});
- From URL : 在<table>的屬性加上 data-url = "jsonURL...",注意格式必須是json,bootstrapTable幫你把呼叫的程式都做完了

3. 調整Column寬度 

- 範例裡面並沒有講解清楚,而且根據目前版本的實作,Column的width並沒辦法真的限制住Column的寬度,當呈現的資料有換頁時,寬度還是會動態的改變
  要限定Column的寬度照範例的話,是在<th>內加上一個class "col-xs-1","col-xs-2",....."col-xs-n" 他會照比例來限制資料寬度

4. RowStyle , CellStyle

Bootstrap Table提供一個讓你可以動態的customize style的方式,分成在<table>中的屬性 data-row-style 以及在<th>層中的屬性 data-cell-style,用rowstyle舉例
- 在<table>中加屬性 data-row-style="myRowStyle"
- 在JS中加一個function叫做 myRowStyle(item, i){} 並且回傳一個物件{classes : "xxx" , css : "disable:true"}
     注意這邊只有兩個key是合法的 classes & css
     給你item跟index讓你自由的判斷要回傳那些,回傳空的{}也行

- Bootstrap會自動幫你把clsss跟css加到<tr>上面去

data-cell-style則是加到<td>上面去

5. Sorting

Bootstrap Table有內建排序功能,將資料丟進去之後她會自動幫忙排序,即使分頁也能夠排的很好,Server排序的功能還沒Release。
Sorting 分成
放在<table>的

  data-sort-name="name"  : 預設的排序column name
  data-sort-order="desc" : 預設的order
  data-sortable = 整個Table能不能做sorting, 預設是true

放在<th>中的
  data-sortable="true" : 這個column能不能sort,預設是false
  data-order = "asc" : 排序方式
  data-sorter = "mySorterA" : 會呼叫mySorterA這個JS的function(a,b){} ,回傳1是a>b ; -1是b>a

 6. formatter 

除了用data-cell-style指定動態的class, css之外,也有另一種可以操作整個Column的顯示方式,回傳的是整個html。
舉例來說,如果Server來的資料只是url,可以幫它包裝成<img>

在<th>中
data-formatter="myFormatterA" ,會去呼叫function myFormatterA(value, row, index),回傳值為html string
把value, index跟整個row都給你參考了,應該會很好實作

 

 7. Column Select

Bootstrap Table提供讓使用者可以自己勾選想要顯示的欄位

<table>下

data-show-columns="true" : Show出可以選欄位的功能
data-minimum-count-columns="[1|n]" : 限制最少需要顯示多少欄位,當欄位數小於這個數字,則不能再取消顯示任何欄位(會被disable掉)

<th>下

data-visible="false" : 預設值是true。如果選擇是false,則一開始不顯示,但是可以從選單內再勾選顯示回來
data-switchable="false" : 預設值是true。這個column是不是可以被選擇顯示/不顯示的選項之一,如果是false,則不會出現在Column Select的選單內 

8. Toolbar

Table上方可以放一些功能按鍵,分成預設按鈕與客製化。

預設按鈕 :

data-search="true" : show搜尋列
data-show-refresh="true" : show refresh按鈕
data-show-columns="true" : show選擇顯示column的功能鈕

客製化Toolbar

其實就是bootstrap本身支援的功能,看你是要用class="btn-group"還是要calss="form-group",參考http://getbootstrap.com/components/

步驟如下 : 
- 在<table>放上你的客製化toolbar div並放上id="abcTool"
- 在<table>內的屬性指定 data-toolbar="#abcTool"

9. Search

在<table>加上屬性 data-search="true" 就可以搜尋所有的column。
如果想要限制只能搜尋某些column,就在<th>的屬性加上data-searchable="false" (預設是true)

10. Paging

只需要加一個屬性就可以把分頁做好了

data-pagination="{true|false}" : 是否要有分頁功能
data-page-number = 1 : 一開始在第幾頁
data-page-size = 10 : 預設一頁幾筆資料
data-page-list = "[10, 25, 50, 100]" : 一頁幾筆資料的選項

data-side-pagination="{client|server}" : 如果值是server,則每次換頁都會去跟Server要資料,給的參數為 limit, offset, search, sort, order

而回傳值則是這樣{
    total : 1000 ,
    rows : [{id:"1", name : "Hank"}, {id:"2", name="someone"}]

 

minglight 發表在 痞客邦 留言(0) 人氣()

談JSONP之前要先談一下瀏覽器的限制 :

    瀏覽器是不允許存取不同domain的資源(JSON, HTML, XML...etc), 也就是說, 你沒辦法用Javascript去讀別人網站的內容, 唯一能做的就是用iframe把別人網頁內容顯示出來而已

為什麼可以用JSONP可以呼叫別的網站的內容, 這是漏洞嗎? 

    瀏覽器是可以允許你去執行別的網站的JS檔, 也許你有用過但是沒有注意到, 你曾經直接用<script> 去執行jquery的script.
    也就是說執行JS是允許的, 但是不能去撈別人網站資料來改. 這也就是為什麼會有cross site script attack的原因 (所以有做留言版的功能的記得要擋掉<script>tag)

什麼是JSONP?

    JSONP其實就是騙瀏覽器, 把你本來要的資料當成Javascript執行, 但是也需要一些條件,
   
    用jquery舉例來說, 你想要得到別的網站的user information, 格式為 {user : 'Hank'}, 你需要這麼做

    Browser端 

    1. $.ajax的option, dataType : 'jsonp' 

         讓browser把回傳的東西當做javascript執行

    2. create global function : function handleUser(data){.......}

        Server回傳的text長這樣 : "handleUser({user : 'Hank'});", 然後瀏覽器就會乖乖執行了

    3. 告訴Server傳回的function名稱

        一般來說會加一個querystring : callback=handleUser => http://xxx.xxx.com?callback=hanldleUser

 

  Server端 : 

    1. 收到request時, 要分析如果有querystring是callback, 要把本來回傳的json, 外面包一個function name => "handleUser({json....});"

  錯誤處理 : 

    基本上你使用JSONP是沒辦法錯誤處理的, jquery的$.ajax就有提到, error這個function不會被呼叫到! 你也沒辦法得到error code以及response等資訊

    現在只有一種做法就是設定timeout, 如果太久沒有回應, 就執行timeout的function

    這裡有一個jquery lib : jqeury-jsonp https://github.com/jaubourg/jquery-jsonp/blob/master/doc/API.md

    幫你implement timeout處理, 以及語法錯誤處理 XD



    

minglight 發表在 痞客邦 留言(0) 人氣()

定義 :

在一個巢狀function的內部, child function使用到outter function的local var時, 會把local var綁著.
這時候如果inner function變成回傳值傳出去, 或者是被當作參數丟進去某個function中, 都會綁著這個Local var.

前情提要 : 

1. local var
    在一個function內, 用var xxx宣告的變數, 稱為local variable. 他的生命週期就在這個function的"{" 到 "}", 如果出了function還呼叫這個變數, 就會出現var不存在的錯誤訊息

    Note : 什麼不是local var => 
               a.  在最外層用var ooo宣告的變數, 其實他是window的成員變數
               b.  在function內部用this.xxx宣告的變數, 他是這個function被new起來之後的成員變數

2. 什麼是巢狀function
    function outter(){
      function inner(){

        }
 }
    
用法與時機 : 

      如果你要使用一個API, 但是這個API紙可以傳function, 卻沒有辦法傳參數進去的時候, 就可以用Closure的方式把變數傳進來

ex1 : 跑Clock, 把傳進來的i綁起來.

1.1 標準的巢狀function

function outter(i){
   function inner(){
       document.getElementById('clock').html = i;
       i = i *2;
   }
   setInterval(inner, 1000);

}
outter(1);

or 

1.2 inner是anonymous function

function outter(i){
   
   setInterval(function(){
       document.getElementById('clock').html = i;
       i = i *2; 
   }, 1000);

}
outter(1);

or

1.3 比較常見的closure寫法, inner被當成function傳出去

function outter(i){
   return function(){
       document.getElementById('clock').html = i;
       i = i *2;
   }
   
}

setInterval(outter(1), 1000);

 ex2 : jquery的queue() and dequeue()
 
 參考這篇 http://minglight.pixnet.net/blog/post/37899609 先研究一下queue()的用法

 基本上就是使用queue的setter, 而運用上跟setInterval()是一樣的, 差別在於queue()你可能會放一些不同參數的function進來, 而這就是Closure美妙的地方, 你可以儘管綁架你想要的各式各樣的local var, 但是對queue()來說, 傳進來的只是個無參數的function, 他要做的只是執行他而已.



  


 

 

minglight 發表在 痞客邦 留言(0) 人氣()

The error happens when I try to add a job to a sql server.

The whole error message :   Description: "Login failed for user 'everest_user'.".  End Error  Error: 2013-12-09 11:01:41.14     Code: 0xC020801C     Source: EvalUserSessionDetail OLE DB Destination [94]     Description: SSIS Error Code DTS_E_CANNOTACQUIRECONNECTIONFROMCONNECTIONMANAGER.  The AcquireConnection method call to the connection manager "vmsdsqlpg01<c/>3180" failed with error code 0xC0202009.  There may be error messages posted before this with more information on why the AcquireConnection method call failed. 

DB Version : SQL Server 2008 R2
SSIS Version : From Visual Studio 2008

Solution : 比對了SQL Server Job上的所有設定, 都跟本來可以RUN的程式沒有兩樣, 所以就參考了http://stackoverflow.com/questions/748136/acquireconnection-method-call-to-the-connection-manager-excel-connection-manage
            在Visual Studio上把Delay Validation改成True就可以了

PS. 本來的設定上, SSIS的Delay Validation是False, 但還是可以run, 一整個很奇怪,不過還好解決了

minglight 發表在 痞客邦 留言(0) 人氣()

做轉檔的時候發現其中一些檔案資料跟資料庫拼不起來.

細心如我,早就對每一個檔案的input trim過了, 資料對不起來一定是特殊字元在作怪.

後來才發現, 把他印出來才發現是個沒有被trim掉的空白在作怪.

1. Google找到的 unicode 印出法

    System.out.println("space" + Integer.toHexString(' ' | 0x10000).substring(1));

2. Unicode

    一般的空白為\u0020, 這種non-break space (nbsp)為\u00a0

3. Wiki 

    http://en.wikipedia.org/wiki/Non-breaking_space
    很難從Window打出來, mac的話是"option + space"就可以打出

4. 解法

    無解, 當初我還呼叫了Apach commons StringUtils.trimToEmpty, 還是沒辦法trim掉.
    所以基本上就是自己寫一個一樣的Util, 加上這一段邏輯 str.replaceAll("\u00a0","")

文章標籤

minglight 發表在 痞客邦 留言(0) 人氣()

Table : ExamResult
Columns : ClassNo, StudentNo, Name, Score

 

SELECT *
FROM ExamResult r1
WHERE (
  SELECT count(*)
  FROM ExamResult r2
  WHERE r1.Score < r2.Score and r1.classNo = r2.classNo
) < N
order by classNo, Score desc

分析 :
列出在相同班級裡面,分數比自己大的人, 小於N人

Ex : N=1, 列出各班第1名的

PS. 為何不使用 = (N-1) ,
      例如 (N-1)=0時, 沒有人分數比我高
             (N-1)=1時, 只有一個人分數比我高

      VS. N=1, 分數比我高的人少於1人
            N=2, 分數比我高的少於2人

如果有一個班級 分數排列是 100, 100, 100, 90, 90.
其subquery的結果會是0


使用等於0的 會列出 100, 100, 100
            1的 會列出 (什麼都沒有, 因為還是0)

使用小於1   會列出 100, 100, 100
            2   會列出 100, 100, 100 

=> 使用<才是正解

 

文章標籤

minglight 發表在 痞客邦 留言(0) 人氣()

利用<a href="mailto:[Content]">Click ME</a>來做出效果

[Content] 的內容如下 : 


     [ToEmailList]?key=value&key2=value2

          key = cc, bcc, subject , body

Example : 

<href="mailto:hankx.hsieh@intel.com; tingx.yen@intel.com?cc=mike&bcc=sue&subject=test&body=type+your">Click Me</a>

minglight 發表在 痞客邦 留言(0) 人氣()

是不是想要把自己在模擬器的行為自動化, 做排程, 機器人, 或是測試網頁的工具? HtmlUnit正是你需要的一套Java API!

下面這個範例, 可以讓你在Facebook login, 並且留言 (繁體中文版限定, 經過測試, 英文版跟中文版的DOM排列方式不一樣 = =a )

API版本 : HtmlUnit 2.10 

1. Login Facebook

String email = "";
String pwd = ""; 

WebClient webClient = new WebClient(BrowserVersion.CHROME_16);
HtmlPage page = webClient.getPage("http://www.facebook.com");

HtmlTextInput emailInput = (HtmlTextInput)page.getElementById("email");
emailInput.setValueAttribute(email);
HtmlPasswordInput passInput = (HtmlPasswordInput)page.getElementById("pass");
passInput.setValueAttribute(pwd);
HtmlSubmitInput submitBtn = (HtmlSubmitInput)page.getElementById("loginbutton").getFirstChild();
mainPage = submitBtn.click();

2. Post Message

String msg = ""; 

HtmlAnchor personPageA = (HtmlAnchor)mainPage.getElementById("pageNav").getFirstChild().getFirstChild();
personalPage = personPageA.click();

DomNodeList<HtmlElement> areas = personalPage.getElementsByTagName("textarea");

for(HtmlElement e : areas){
((HtmlTextArea) e).setText(msg);
}
HtmlTextArea input = (HtmlTextArea)personalPage.getElementByName("xhpc_message");
input.setText(msg);

HtmlForm form = (HtmlForm)personalPage.getByXPath("//form[@action='/ajax/updatestatus.php']").get(0);
HtmlSubmitInput submitButton = form.getInputByValue("留言");
if(submitButton == null){
submitButton = form.getInputByValue("Post");
}
submitButton.click();

3. Run Javascript 

personalPage.executeJavaScript("alert('HelloWorld');");

 

後記 & 心得: 

會找這個API,起因是想要塞垃圾資料到某個詐騙網站, 當初只有挖出網站的JS, 然後用IE的Development Tool去Run這些JS. 但是手動的好麻煩阿阿阿~~

找到API之後,開始用FB來測試Login + 留言, 後來索性來試著寫出FB的Robot想要監看留言順便按讚 XD

基本上遇到了不少挫折, 我就放棄了Robot的實做, 其中一個原因是利用Android模擬器應該也寫得出來 

結論 : 

優點我就不多說了,就是讓你可以自動化對瀏覽器做的行為

缺點如下 :

    - 雖然可以選擇瀏覽器版本, 但是似乎沒有模擬的完全接近, 有些版本會有一些莫名其妙的bug跑出來
    - FB的中文版跟英文版的排版不一樣, load message的方式跟順序也有差別, 所以真的要寫出FB能run的程式還真的是不容易
    - 如果網站一改版, 或者是只要有個小地方不一樣, 程式就很有可能會掛掉

建議 :  

     - 找那些Load網頁不會太複雜, Ajax使用上比較少比較簡單的網站比較適合
     - DOM的Select方式要抽離出來, 甚至變成常數檔, 這樣在維護上會比較容易
     - 如果自動化邏輯沒有要跟Server互動(例如存進DB), 只是單純的下指令的話, 可以考慮另外寫一個.js檔案, 直接跑Javascript會是最簡單的方式

參考連結 : 

StackOverFlow : http://stackoverflow.com/questions/7260282/apache-httpclient-4-and-javascript

HtmlUnit : http://htmlunit.sourceforge.net/
HtmlUnit內建了Selenium, 是一個沒有畫面的瀏覽器, 還可以選擇瀏覽器的版本

Selenium : http://seleniumhq.org/

minglight 發表在 痞客邦 留言(0) 人氣()

jQuery的排程其實一開始是拿來做動畫的, 讓某個DOM可以依序的執行指令,但是也可以拿來自定自己的排程.

排程其實是將一堆function利用.data()放入jquery object裡面, 主要分成兩個function, queue() & dequeue()

- getter 

queue( [queueName] ) 

得到這個相關queueName的function.
default ququeName為"fx", 放在不同的queueName的function不會有相關連

- setter

queue([queueName] , func )

將這個function放入對應queueName的funcion中

 - caller 

dequeue([queueName])

依照先入先出的方式拿出function, 並且執行它

使用方法  
分成兩種不同的方式

    1. ququeName為fx, 或是沒有指定 
      - queue會自動開始, 並不需要需要dequeue()就會自動開始, 但是只限於第一個function, 之後還是需要自己呼叫dequeue才能使用 

    2. queueName是自己指定的
       - 要自己呼叫dequeue()才會開始執行第一個function

文章標籤

minglight 發表在 痞客邦 留言(0) 人氣()

一. <script> 與 js檔案

  1. 當瀏覽器遇到<script>時,會停止文件解析,先執行<script></script>之間的程式
  2. window.onload = function(){};避免HTML DOM都還沒形成就在操作
  3. load js檔案 : 瀏覽器會假設載入的.js編碼與HTML網頁編碼相同。如果你的.js網頁與HTML編碼不同,JavaScript中非ASCII相容字元部份就會出現亂碼。 => 都改成UTF8吧!!

二. 安全限制

  1. 另開視窗 : 可以下JS來開啟新視窗,但是不能開size太小而導致使用者看不到的視窗
  2. 取得檔案大小 : Firefox、Chrome中,可以透過(inputObject).files.item(0).size特性
  3. 同源策略(Same-origin policy): 
      a. 哪三樣條件要相同的文件,才會被視為內部文件?
      b. 可以存取iframe內部的條件為何?
      c. 可以將<script>的src屬性指向外部網站嗎? 如果可以,那麼script存取的url資源是指向自己的網站,還是.js相對應的路徑? 

三. 名稱管理

  1. 試著使用匿名函式,並直接呼叫他
  2. 說明為何要使用名稱管理 

四.  建立核心公用程式

  1. 利用暱名程式來宣告一個共用的namespace
  2. 寫出一個each的util 

minglight 發表在 痞客邦 留言(0) 人氣()

一. constructor

  1.  建立物件的兩種方式
  2.  使用new時會回傳的物件型態分別為何?(依照有沒有return)
  3.  function內部的this會指向的物件如何在runtime時找到對應?
  4.  每個物件都會有constructor,用兩種建立物件方式得到的constructor分別為何?
  5.  function名稱其實就是constructor的變數名稱
  6.  說明function.constructor vs. obj.constructor的差別
  7.  利用Closure做出一個getter & setter的function

二. prototype

  1. 說明在呼叫new的時候, prototype會在哪?, 另外constructor又會在哪建立?
  2. prototype是所有該function所形成的實體共用還是分開的?
  3. true or false? 如果prototype的屬性跟物件本身宣告的屬性名稱相同,兩者不能並存, 較晚宣告的屬性會覆蓋較早宣告的.  
  4. 使用prototype宣告method的優點為何?
  5. instanceof 是判斷 prototype or constructor ?

三. 寫出一個function繼承的方式

minglight 發表在 痞客邦 留言(0) 人氣()

一.函式宣告

  1. 回傳值預設為何?
  2. 參數(parameter),引數(argument)的定義
  3. function隱藏變數有哪三個,如何使用
  4. 改變參數的值,也會改到隱藏變數arguments相對應的值嗎?
  5. 使用Option object當成參數時的缺點為何?

二. Function instance
  1. function實際上為Function的instance, 所以function也可以當成引數丟到別的function裡面. 示範用Function對應function的宣告
  2. 說明三種宣告的差別
      function a(){....} 

      var a = function(){};    

      var a = function b(){};

 3. 說明兩種匿名函式的用法
 

三. this指的是誰?

 1. this指的是某個已經產生的instance, 而非某個function內宣告的變數
 2. this是runtime,依照呼叫來決定誰是this對應的instance,而不是宣告在哪個function裡面來決定, 請舉例
 3. 如何改變this的參考? 像是jquery的each()那樣
 4. 說明call() & apply()兩種的用法以及其差別

四. Closure 

 1. Closure的構成條件
 2. 列出Closure步驟
 3. 說明為何要使用Closure

    

文章標籤

minglight 發表在 痞客邦 留言(0) 人氣()

一. 核心

  1.  三大類型型別
  2.  數字型別
  3.  6個被判斷為false的值 
  4.  6種type
  5.  null vs. undefined vs. xx is not defined的差別

二. 變數

  1. 靜態動態的區分條件
  2. 未宣告的變數被assign會直接變成全域變數
  3. 在最外部的區域變數也是window的屬性
  3. delete的用法
  4. function內部區域變數的作用區間

三. 型態轉換

  1. 強弱型別的區分條件 (沒有絕對只有相對)
  2. 真言 : 轉換型別是運算時的轉換,並非改掉原本的型別
  3. primitive type的boxing
  4. parseInt(str, base), parseFloat(str, base)的用法
  5. 字串對於 + 運算子的轉換順序 ;
      字串對於 - , *, /, 運算子的轉換順序
      字串遇到與數字比較>,<的運算子的轉換順序
      字串遇到與字串比較>,<運算子的比較邏輯
  6. true/false 遇到與"數字"運算時的轉換(only 數字)
  7. 除了值相同,型別也要相同的運算子

四. 運算子

  1. 字串&數字的比較大小規則
  2. 物件比較大小的規則 A -> B -> C
  3. 物件使用 "==" 是判斷?
  4. &&, || 並非傳回true, false,而是傳回?
 
五. 物件 
  1. for in只能使用在 Array & literal declaire object
  2. 數字運算的時候,obj會呼叫的method
  3. 字串運算的時候,obj會呼叫的method
  4. 呼叫屬性/method的兩種方法

六. 陣列
      略,too easy

  

minglight 發表在 痞客邦 留言(0) 人氣()

想要用setTimeout來使用delay call loop, 但是參考W3School卻沒有地方可以呼叫參數!!

直接參考Closure, http://minglight.pixnet.net/blog/post/43019938

 

文章標籤

minglight 發表在 痞客邦 留言(0) 人氣()

這篇文章主要是follow GWT的Tutorial來介紹GWT.  
參考Google文件 : https://developers.google.com/web-toolkit/doc/latest/tutorial/

GWT Overview

GWT是給Java developer能夠在寫Web App的時候能夠盡量不使用到Javascript,讓Web client端的程式碼也可以用Java的程式,利用GWT的Complier將Java編譯成Javascript code,而且還能夠相容於各個瀏覽器,這正是GWT最重要的目的。

GWT Client支援的JRE - 參考Google  https://developers.google.com/web-toolkit/doc/latest/RefJreEmulation

好處 : 1. 可以使用Java寫Web程式
         2. 可以使用Eclipse來debug client side的程式!! 就跟debug java一樣!
         3. 不需要管User使用什麼瀏覽器,交給Google來處理就好了! 

缺點 : 1. 需要花時間來學習GWT
         2. 一開始的loading時間會比較長,會稍微比Servlet-JSP慢一些 (只限於develope mode , 感謝Monty大指正) 

插播 : GWT2.0改進的地方 - http://pt2club.blogspot.com/2009_12_01_archive.html

 

Build一個GWT的範例程式 - Stock Watcher

Step1. 開一個新的GWT應用程式

Eclipse -> New Web Project -> check GWT -> done

Step2. 了解需求

連結 :https://developers.google.com/web-toolkit/doc/latest/tutorial/design
基本上就是一個可以新增股票看他會跳動多少的程式,另外需要計算漲跌

Step3. 建立UI

UI展示&Source http://gwt.google.com/samples/Showcase/Showcase.html?locale=en 
UI Gallery(Widget & Panel) https://developers.google.com/web-toolkit/doc/latest/RefWidgetGallery

上面沒有提到的Panel,實際上就是一個block的<div>
ex : <div class="gwt-Label">Last update : Oct 1, 2008 1:31:48 PM</div>

Layout Panel : 
在GWT2.0以前,沒有Layout Panel這個Class,都是使用一般的Panel去操作. 
2.0以前的缺點 :
    1. 不可預測的Layout
    2. 常常需要用其他的程式碼去fix

2.0之後使用Layout Table : 
    1. 完全可以預測(乖乖的呈現)
    2. 可以使用動畫去操作變化 

使用Layout Panel注意事項

參考 : https://developers.google.com/web-toolkit/doc/latest/DevGuideUiPanels#Design

1. 所有的Layout Panel都要包在RootLayoutPanel之內,RootLayoutPanel extends LayoutPanel, 允許在裡面的Panel加入一些限制條件

2. 也可以使用UIBinder來新增LayoutPanel的效率,UIBinder是使用新的XML language來建立新的layout,有點類似andorid. 效果會比翻譯之後的JS快.
    UIBinder : https://developers.google.com/web-toolkit/doc/latest/DevGuideUiBinder 
3. 各種Layout Panel簡介

DockLayoutPanel : 用東南西北來新增元件
SplitLayoutPanel : 類似DockLayoutPanel,但是內部各個元件都可以resize
TabLayoutPanel : 可以一次assign

4. LayoutPanel的功能只限於Panel, 其他的Widget基本上是不受影響的 

實做StockWatcher - 重點分享


1. 將需要的元件都放在成員變數上(因為可能會有多個method共用) 

2. Debug模式只需要refresh瀏覽器就可以了 (只限於Client-side code)

3. 畫面事件文件 - 非常好的模式!! 容易溝通簡單明瞭! 可以學起來

Task UI Event (Trigger mechanism) Response
User enters a stock code. Clicks the Add button
or presses return in the input box.
  • Verify input.
  • Check if stock already exists.
  • Add a new row.
  • Create a delete button.
User deletes stock from the table. Presses the Remove button.
  • Remove row from table.

 PS. GWT1.6之後很多XXXListener都被Handler取代了
 (原文)Starting with GWT 1.6, the ClickHandler, KeyDownHandler, KeyPressHandler, and KeyUpHandler interfaces have replaced the now deprecated ClickListener and KeyBoardListener interfaces.

4. 通常會用一個List暫存Table的key來做為後續update,delete的用途

5. Timer可以變成一個Single Thread的用途, ex : timer.schedule(int) => setTimeout() ; timer.scheduleRepeating(int); => setInterval();

6. 設定CSS檔案的地方有兩個

  •     moduleName.gwt.xml
  •     xxx.html直接使用<link>   

7. 修改CSS的方式

    A. 直接在CSS檔案內部修改 - 適用在此module所有的Widget
    B. 在元件新增一個Class
    C. Override預設元件的style.(primary style) ex : <button class="gwt-Button" tabindex="0" type="button">Add</button> 
    D. 直接inline方式改掉style
    E.  改Theme

 8. Theme
    在moduleName.gwt.xml裡面有Theme的設定,可以修改來改變預設的Theme. 

 9. Deffered binding
     在Production mode, GWT會依照browser給不同適應的js.
     如果有實做i18n, 也會依照不同的language給不同的語言設定

 10. 利用Annotation的方式實做i18n
       GWT提供一套系統來實做i18n
       參考Google文件 : https://developers.google.com/web-toolkit/doc/latest/tutorial/i18n

  11. Serializable
       使用Serializable & gwt的 isSerializable都可以(google比較建議使用isSerializable),因為client的JRE並沒有支援java.io的package
       能夠被GWT的client side使用的物件有 :

  • The type is primitive, such as charbyteshortintlongbooleanfloat, or double.
  • The type an instance of the StringDate, or a primitive wrapper such as CharacterByteShortIntegerLongBooleanFloat, or Double.
  • The type is an enumeration. Enumeration constants are serialized as a name only; none of the field values are serialized.
  • The type is an array of serializable types (including other serializable arrays).
  • The type is a serializable user-defined class.
  • The type has at least one serializable subclass.
  • The type has a Custom Field Serializer

   12. 錯誤處理
       一般在呼叫Service的時候,產生錯誤(例外)分成兩種情形 : 有宣告throws錯誤 vs 沒有宣告throws錯誤

  • 沒有宣告throws錯誤 : 只會在onFaliure(Throwable ex)得到InvocationException with msg "The call failed on the server; see server log for details"
  • 有宣告throws錯誤 : 可以在onFailure(Throwable ex)得到跟Server side一樣的Exception

   13. JSNI
       將已經有的Javascript lib轉換成可以被GWT呼叫的method. https://developers.google.com/web-toolkit/doc/latest/DevGuideCodingBasicsJSNI 

   14. RPC serviceImpl就是 [Servlet]      

 

晚場插播 : 查到的GWT中文網站

don't carehttp://blog.dontcareabout.us/ 

GWT 技術筆記本http://gwt-note.psmonkey.org/index

  

minglight 發表在 痞客邦 留言(2) 人氣()

1 2