Dojo 日期控制項的國際化和整合

來源:互聯網
上載者:User

 

Dojo 日期控制項類型

  Dojo 目前支援兩種日期控制項:

圖 1. dijit.form.TimeTextBox

  該類型控制項為時間控制項 , 圖中顯示格式為 :hh:mm:ss,該控制項支援國際化 , 其格式會根據國家的不同而相應變化。

圖 2. dijit.form.DateTextBox

  該類型控制項為日期控制項 , 圖中顯示格式為 :yyyy-MM-dd,該控制項也支援國際化。

  Dojo 日期控制項的類階層

圖 3. Dojo 日期控制項類結構圖

  圖 3 列出了 Dojo 日期控制項所依賴的主要組件,下面分別介紹它們的功能:

  dijit.form._ FormiWidget

  所有 dijit 控制項的基類,定義了 Dojo 控制項的一些共有特徵,如 id,name 屬性,onFocus,onChange 事件等。

  dijit.form.TextBox

  普通 html 文字框的一個封裝。

  dijit.form.ValidationTextBox

  提供驗證功能的文字框 , 子類可重寫 isValid() 方法來自訂驗證規則。

  dijit.form.MappedTextBox

  提供了一個和文字框對應的隱藏欄位,用於存放 dojo 內部處理的結果 , 並提供了一個方法 serialize 來在內部值和顯示值之間轉化。

  dijit.form.RangeBoundTextBox

  可定義取值範圍的控制項,並提供一個介面 isInRange 來判斷是否在給定範圍內。

  Dojo 日期控制項的初始化

  Dojo 提供了兩種初始化控制項的途徑:聲明方式和編程方式。

  聲明方式

  通過給 html 控制項添加 dojoType 屬性,其值為 dojo 控制項的類名,在載入頁面的過程中 Dojo 會將指定了 dojoType
的控制項轉為 dojo 控制項,如 <input type="text" dojoType="dijit.form.TimeTextBox"
id="text001"> 。在頁面載入完成後會轉變為一個 dojo 時間控制項。

  Dojo 是如何把普通的 html 控制項轉換為 dojo 控制項的呢? dojo.parser 在其中起了主要的作用。 dojo.parser
會遍曆頁面取出有 dojoType 屬性的 html 元素,根據 dojoType 的值來初始化 dojo
控制項對象,同時會把頁面中該元素的屬性值做為參數傳遞給初始化方法,Dojo 把參數值轉換為自己需要的類型。例如 :<input type="text"
dojoType="dijit.form.TimeTextBox" id="text001" value="T14:22"> 在頁面載入的時候 dojo
會初始化 dijit.form.TimeTextBox 類型的控制項,同時會把 value="T14:22" 做為參數傳給初始化方法,但由於
dijit.form.TimeTextBox 對應的 value 屬性的值是 Date 類型,所以 dojo.parser 會對其進行轉換。此時會用到 dojo
日期轉換功能,在後面會詳細介紹,代碼如下 :

清單 1. 聲明方式初始化 dojo

<script djConfig="parseOnLoad:true,isDebug:true,locale:'zh-cn'"src="<%=Context%> 
 /javascript/dojo/dojo.js" ></script> 
 <script type="text/javascript"> 
 dojo.require("dojo.parser"); 
 dojo.require("dijit.form.TimeTextBox"); 
 </script> 
 <body class="tundra"> 
 <input type="text" id="text001" dojoType="dijit.form.TimeTextBox" value="T14:22">

圖 4. Dojo 日期控制項類結構圖

  編程方式

  dojo 允許以更加物件導向的方式來使用 dojo 控制項。對於上面的例子,可以採用如下方式來初始化。

new dijit.form.TimeTextBox( 
 {"id":"text002","value":dojo.date.locale.parse(" 下午 2:22",{selector:"time"})}, 
 dojo.byId("text001"));

  該方法有兩個參數 , 第一個為 dojo 對象屬性值的一個集合,第二個參數指出了 dojo 控制項在頁面上的位置,在此例中 id 值為 text001
的 html 元素將被替換為 dojo 控制項(註:原來的 html 控制項將被移除)。第一個參數中我們同樣有兩個屬性 id 和 value,由於編程方式定義的
dojo 控制項不再經過 dojo.parser 處理,因此 value 屬性的值必須是日期類型,我們用 dojo.date.locale.parse
方法來將字串轉換為 Date 類型,此處我們會看到同樣是把字串轉換為 Date 類型,不同的方法資料格式會有很大不同,稍後會對此進行詳細介紹 ,
詳細代碼如下:列表 (lists) 是文章中常用的元素。列表分為有序列表 ( 帶有數字順序的列表 ) 和無序列表 ( 不帶數字順序的列表 ) 。

清單 2. 編程方式初始化 dojo

<script djConfig="parseOnLoad:true,isDebug:true,locale:'zh-cn'"src="<%=Context%> 
  /javascript/dojo/dojo.js" > 
  </script> 
 <script type="text/javascript"> 
  dojo.require("dojo.parser"); 
  dojo.require("dijit.form.TimeTextBox"); 
 </script> 
 <body class="tundra"> 
  <input type="text" id="text001"> 
    <script> 
      new dijit.form.TimeTextBox( 
      {"id":"text002","value":dojo.date.locale.parse 
      (" 下午 2:22",{selector:"time"})},dojo.byId("text001")); 
    </script>

圖 5. 編程方式初始化 dojo 效果

  我們可以看到,這兩種方式所產生的效果是完全一樣的。聲明方式定義 dojo 控制項實現起來比較簡單,而且 dojo.parser
協助我們做了很多輔助工作。編程方式稍微複雜些,但相比聲明方式,編程方式更靈活,我們可以很方便的控制它的初始化過程。

  兩種方式結合

  當然有些情況下會有這種需求 , 既想擁有編程方式的靈活性,又想擁有聲明方式的簡單性,比如我想自己來控制什麼時候產生 dojo
控制項,又不想自己寫方法來進行參數值轉換,可通過如下方式來實現,在 html 代碼中不添加 dojoType 屬性,在我們需要的時候,通過編程方式來指定 html
控制項的 dojoType 屬性值,然後通過調用 dojo.parser.instantiate() 方法,來解析 html 代碼產生 dojo
控制項,這樣我們既能動態控制 dojo 控制項的產生,又能利用 dojo.parser 的強大功能,對於上面提到的例子我們可採用如下代碼實現:

清單 3. 兩種方式結合頁面代碼

<script djConfig="parseOnLoad:true,isDebug:true,locale:'zh-cn'"src="<%=Context%> 
  /javascript/dojo/dojo.js" > 
  </script> 
 <script type="text/javascript"> 
  dojo.require("dojo.parser"); 
  dojo.require("dijit.form.TimeTextBox");  
  function createDojo(inputId){ 
    var inputObj = document.getElementById(inputId); 
    inputObj.setAttribute("dojoType", "dijit.form.TimeTextBox"); 
    dojo.parser.instantiate([inputObj]); 
  } 
 </script> 
 <body class="tundra"> 
  <input type="text" id="text001" onfocus="createDojo('text001')"> 
 </body>

  其頁面效果同前兩種方式完全一樣。

  Dojo 日期控制項的國際化策略

  上一節對 Dojo 日期控制項做了一個整體介紹,我們瞭解了 Dojo 的類階層以及如何使用 Dojo 。本節主要介紹 Dojo
日期控制項對時間的處理以及對國際化的支援。

  Dojo 日期控制項對時間的處理

  由於大部分 dojo 控制項都繼承自同一個基類,所以他們擁有相似的行為方式:

  都通過 onfocus 事件來觸發 dojo 控制項;

  如果繼承自 dijit.form.ValidationTextBox,都通過 onkeyup 事件對值進行校正;

  都通過 onBlur 事件來關閉 dojo 控制項等等。

  日期控制項同樣具有上述行為,相應時間分別為:

  Onfocus:開啟日曆視窗,並對當前值進行校正;

  Onkeyup:對當前值進行校正;

  onBlur:關閉日曆視窗,並對當前值進行校正。

  瞭解了 Dojo 日期控制項的事件,下面將介紹我們 Dojo 提供的用於資料處理的方法 setValue() 和 getValue() 。

  setValue 方法

  在日期控制項初始化時會給其傳遞一個 Date 類型的初始值,在初始化方法中正是通過調用 setValue() 來對其進行付值的
setValue(Date):在該方法中會進行兩個操作:用 format 屬性定義的方法將 Date 類型資料轉換為字串,存到 textbox 的 value
屬性中,textbox 是我們可以在頁面看到的 dojo 日期控制項中的文字框;用 serialize 屬性定義方法將 Date 類型資料轉換為字串存到
valueNode 的 value 屬性中,valueNode 既為 textbox 所對應的隱藏欄位。 dijit.form.TimeTextBox 中預設的
format 方法為 dojo.date.locale.format, serialize 方法為 dojo.date.stamp.toISOString

  getValue 方法

  getValue() 方法返回的是日期控制項的實值型別為 Date 。上面提到 dojo 日期控制項的兩個域 textbox 和 valueNode
中儲存的都是字串類型資料,因此該方法中會將其轉換為 Date 類型 .dijit.form.TimeTextBox 預設使用的是
dojo.date.locale.parse (/*String*/value, /*Object?*/options) 方法該方法會根據指定的 locale(
在 djConfig 中指定 ) 和格式 ( 在輸入參數 selector 屬性中指定 ) 來將 textbox 中的值轉換為 Date 類型。

  Dojo 日期控制項對國際化的支援

  Dojo 日期控制項對國際化的支援主要集中在 dojo.date 包下的兩個類 dojo.date.locale 和 dojo.date.stamp

  dojo.date.stamp

  基於 ISO-8601 標準,在 Date 和 String 類型之間進行轉換。 ISO-8601 支援的格式如下:

日期 
  yyyy 
  yyyy-MM 
  yyyy-MM-dd 
時間 
  THH:mm 
  THH:mm:ss 
  THH:mm:ss.SSS

  dojo.date.stamp 類中包含的方法為:

  dojo.date.stamp.fromISOString

  用於把 String 轉為 Date.

  例 : dojo.date.stamp.fromISOString("2005-06-30T08:05:00");

  轉換後的 Date 類型在 Firefox 下用 Firebug 列印的結果如下 :

圖 6. Dojo 實際儲存的日期值

  而 dojo.date.stamp.fromISOString("2005-06-30 T08:05:00");

  因為不符合 ISO-8601 標準,將產生一個空的 Date 對象。

  dojo.date.stamp.toISOString

  用於把 Date 轉為 String

  例:dojo.date.stamp.toISOString(new Date())

  上面提到過,如果採用聲明方式產生 Dojo 日期控制項,則 Dojo 會用 dojo.date.stamp.fromISOString
方法來對其初始化,因此我們在給控制項複值的時候必須遵循 ISO-8601 標準,否則將會產生一個空值 . 如何在初始化時,讓 Dojo
接受非標準格式的資料呢?我們知道,Dojo 日期控制項用兩個域來存放資料 :textbox 和
valueNode,無論初始化時它如何對資料進行處理,最終的結果都是存在這兩個域裡,所以我們可以將我們的值直接複給這兩個域,這樣即使
dojo.date.stamp.fromISOString() 方法轉換失敗,我們也能將值賦給 Dojo 。例如:

清單 4. 直接給 dojo 隱藏欄位賦值

<script type="text/javascript"> 
  dojo.require("dojo.parser"); 
  dojo.require("dojo.date.stamp"); 
  dojo.require("dojo.date.locale"); 
  dojo.require("dijit.form.TimeTextBox");  
  function createDojo(inputId){ 
    var obj = dojo.byId(inputId); 
    var value = obj.value; 
    obj.setAttribute("dojoType", "dijit.form.TimeTextBox"); 
    dojo.parser.instantiate([obj]); 
    obj = dijit.byId(inputId); 
    obj.textbox.value = value; 
    obj.valueNode.value = value; 
  } 
 </script>

  當然 Dojo 並不推薦我們這樣做,畢竟它已經向我們提供了對其值進行操作的介面:setValue() 和 getValue()
。但由於聲明方式中我們沒有機會接觸到這兩個方法,所以如果不採用強制複值的方法,我們只能通過編程方式來產生 Dojo 。在編程方式中,我們直接傳遞一個 Date
對象給 Dojo 而非字串,所以在傳遞之前,可以自己定義轉換方式來將 String 轉為 Date 。

清單 5. 通過 dojo 提供的介面來賦值

<script type="text/javascript"> 
 <script type="text/javascript"> 
  dojo.require("dojo.parser"); 
  dojo.require("dojo.date.stamp"); 
  dojo.require("dojo.date.locale"); 
  dojo.require("dijit.form.TimeTextBox"); 
 </script> 
 <body class="tundra"> 
  <input type="text" id="text001"> 
  <script> 
    new dijit.form.TimeTextBox({"id":"text002","value":dojo.date.locale.parse 
    (" 下午 2:22",{selector:"time"})},dojo.byId("text001")); 
    </script> 
 </body>

  此處用到了 dojo.date.locale.parse 方法,下面會詳細介紹。

  Dojo.date.locale

  基於指定的 locale,在 String 和 Date 之間進行轉換。

  主要介紹兩個方法:dojo.date.locale.parse() 和 dojo.date.locale.format() 。

  dojo.date.locale.parse()

  用於把字串按照指定參數轉換為日期類型

  其中字串的格式必須和當前頁面的 locale 相匹配,否則轉換將失敗 , 例 :

清單 6. 字串轉換為日期類型代碼 1

<script djConfig="parseOnLoad:true,isDebug:true,locale:'zh-cn'" src="<%=Context%> 
  /javascript/dojo/dojo.js" > 
  </script> 
 <script> 
  dojo.date.locale.parse("12:30",{selector: "time"}); 
 </script>

  執行的結果為空白,說明轉換失敗。 因為 locale: zh-cn 對應的時間格式為“下午 12:30 ”如換成如下代碼 :

清單 7. 字串轉換為日期類型代碼 2

<script djConfig="parseOnLoad: true, isDebug: true, locale:'zh-cn'" src="<%=Context%> 
  /javascript/dojo/dojo.js" > 
  </script> 
 <script> 
  dojo.date.locale.parse(" 下午 12:30",{selector: "time"}); 
 </script>

  則能轉換成功。由此可以看到,如果要將字串轉為日期類型,字串的格式必須和當前頁面的 locale 相匹配,這就對轉換增加了一些約束。

  dojo.date.locale.format()

  用於把日期類型按照指定的格式轉換為字串。

  在將日期類型轉換為字串時,並不要求必須與 locale 相匹配,因此使用起來更靈活些,例

清單 8. 日期轉換為字串代碼 1

dojo.date.locale.format(new Date(), {selector:'time', timePattern:'HH:mm:ss'});

  轉換後結果為 : 10:18:41

清單 9. 日期轉換為字串代碼 2

dojo.date.locale.format(new Date(), {selector:'date', datePattern:'yyyy-MM-dd'});

  轉換後結果為 : 2008-10-10

清單 10. 日期轉換為字串代碼 3

dojo.date.locale.format( 
  d,{selector:'datetime', datePattern:'yyyyMMdd',timePattern:'HHmmss'});

  轉換後結果為 : 20081010 101841

  上述方法在 Dojo 日期控制項中的應用

  上面介紹了 dojo 提供的用於時間處理的一些工具,下面將介紹 dojo 日期控制項是如何使用這些工具的。在給 dojo 日期控制項負值的時候,會用
format 屬性定義的方法將其轉化為字串存到 textbox, 做為顯示值用 serialize 屬性定義方法將 Date 類型資料轉換為字串 存到
valueNode,做為 dojo 日期控制項的實際值在從 dojo 日期控制項取值的時候,用 parse 屬性定義的方法,將 textbox 中的值轉換為
Date 類型。

  format 屬性對應的方法為 dojo.date.locale.format, ;

  serializet 屬性對應的方法為 dojo.date.stamp.toISOString ;

  parse 屬性對應的方法為 dojo.date.locale.parse ;

  format 方法 :dojo.date.locale.format

  會根據指定的格式對 dateObject 進行轉換。

  我們可以通過在頁面中如下配置來指定 locale: <script djConfig="parseOnLoad: true, isDebug:
true, locale:'zh-cn'"> 對於日期格式可在輸入參數 options 的 selector 屬性中定義。目前 dojo 支援三種格式
:date,time,timestamp 。但 dojo 只對前兩種定義了控制項類 dijit.form.DateTextBox 和
dijit.form.TimeTextBox,如果我們需要 timestamp 類型的控制項可通過擴充 dijit.form.TimeTextBox
來實現,代碼如下:

清單 11. 擴充 dojo 日期控制項

dojo.declare("dijit.form.TimestampTextBox",dijit.form.TimeTextBox,{ 
  postMixInProperties: function(){ 
    this.inherited('postMixInProperties', arguments); 
    this.constraints.selector = 'timestamp'; 
  } 
});

  當然也可以自訂 format 方法來對 Date 類型進行轉換 .

  serialize 方法 : dojo.date.stamp.toISOString

  按照 ISO-8601 標準來對 Date 類型進行轉換,轉換後的值被存在 valueNode 裡,而此值是 dojo
日期控制項的真實值,所以如果其格式不能滿足我們的要求時,可通過自訂 serialize 方法來解決 , 例:中國時間上午 10:17 在頁面中顯示為:上午
10:17,如果用預設的 serialize 方法則其真實值為 :T10:17:00, 我們看到時間前多了個 T, 如果我們想最終結果為 10:17:00,
則可如下定義 serialize 方法 .

清單 12. 自訂 serialize 方法

function(d, options) { 
  return dojo.date.locale.format( 
    d, {selector:'time',timePattern:'HH:mm:ss'} 
  ); 
 }

  在上面已經詳細介紹了這幾個方法,如果在實際應用中,上述方法不能滿足要求時,我們可以通過更改相關屬性對應的方法來達到目的。同時,我們注意到,上述方法中都有一個
options 參數,該參數是用來指定轉換的格式的,它是一個 Object 類型的資料,對應以下屬性:selector: 用來指定要轉換的類型,dojo
已定義的值有 date( 只轉換日期部分 ) 和 time ( 只轉換時間部分 ), 如果為其他值則將會把 date 和 time 都包括進來

  formatLength: 轉換後字串的長度 可選值有 long, short, medium , full 預設是 short

  datePattern: 日期部分的格式

  timePattern:時間部分的格式

  locale:設定國際化參數

  與後台系統的整合

  通過以上對 Dojo 日期控制項國際化支援的介紹,我們知道 Dojo 作為一種流行的 Javascript
開源架構,其對日期國際化的支援非常強大。目前的很多 Web 應用程式都是基於 Dojo
來實現日期的國際化。但不是每個背景系統對日期國際化的支援都是那麼強大,有些後台系統可能對日期國際化的支援比較有限,這時如果需要將 Dojo
和這些後台系統進行整合來支援日期國際化的時候,就需要我們做一些額外的開發工作。這裡我們以 IBM 的 DB2 Content Manager 來舉例說明
Dojo 如果和跟後台系統進行整合,同時我們也給出一些整合方面的開發技巧。

  IBM DB2 Content Manager 對日期國際化的支援:

  DB2 Content Manager 是建立在 DB2 Universal Database? 預存程序基礎上的內容儲存庫,利用了 IBM
WebSphere Application Server 提供的內容檢索和安全性以及 Tivoli? Storage Manager
提供的對象遷移及備份與恢複。 CM 可作為結構化和非結構化資料的企業儲存庫用來儲存任何格式的文檔。 DB2 Content Manager 支援內容國際化
(Globalization),但是對日期類型的國際化支援的並不是很好。比如,對於 Date 類型的資料,CM 要求其格式必須是 yyyy-MM-dd 。
如果某一個國家預設的日期格式是 MM-dd-yyyy,這種格式的日期資料是沒法保持到 CM 中的,唯一的辦法是將其它日期的格式轉成 yyyy-MM-dd
格式,然後再進行儲存。下面列出 CM 支援的日期格式:

清單 13. CM 支援的日期格式

Type Format
Date yyyy-MM-dd
Time HH.mm.ss 或 HH:mm:ss
Timestamp yyyy-MM-dd-HH.mm.ss.SSSSSS
或 yyyy-MM-dd
HH:mm:ss.SSSSSS

  通過以上對 CM 支援的日期格式的分析,我們可以得出結論:對於要儲存到 CM 的日期資料需要先進行格式轉化,然後再儲存。在使用 Dojo
作為前台,CM 作為背景 Web 應用程式開發中,Dojo 在前台 Web 頁面對日期國際化的支援非常強大,因此需要在 Dojo 日期控制項把日期傳到後台 CM
時先把日期轉成 CM 能夠支援的格式,流程圖如下:

圖 7. Dojo 和 CM 日期轉換流程圖

  查看原圖(大圖)

  通過上面的流程圖我們可以清楚的知道,在 Dojo 日期控制項向 CM 傳送日期資料之前需要對日期進行格式轉換,下面針對
Date、Time、Timestamp 三種類型的資料分別介紹如何進行日期轉換:

  Date

清單 14. Date 類型轉碼

  dojo.declare("MyDateTextBox",[dijit.form.DateTextBox],{ 
  serialize: function(d, options) { 
    return dojo.date.locale.format( 
      d, {selector:'date', 
        datePattern:'yyyy-MM-dd', 
        timePattern:'HH:mm:ss'}).toLowerCase(); 
  }, 
 });

  說明:定義自己的 dojo Date 控制項,需要繼承 dijit.form.DateTextBox (Dojo 中預設的 Date 控制項 )

  重載 dijit.form.DateTextBox 中的 serialize 方法:指定當前控制項的類型為 date (selector: ’ date
’),將控制項中的 Date 值轉成 yyyy-MM-dd 格式。

  Time

清單 15. Time 類型轉碼

  dojo.declare("MyTimeTextBox",[dijit.form.TimeTextBox], { 
  serialize: function(d, options) { 
    return dojo.date.locale.format( 
      d, {selector:'time', 
        datePattern:'yyyy-MM-dd', 
        timePattern:'HH:mm:ss'}).toLowerCase(); 
  }, 
 });

  說明:定義自己的 dojo Time 控制項,需要繼承 dijit.form.TimeTextBox (Dojo 中預設的 Time 控制項 ); 重載
dijit.form.TimeTextBox 中的 serialize 方法 : 指定當前控制項的類型為 time (selector: ’ time ’),
將控制項中的 Time 值轉成 HH:mm:ss 格式。

  Timestamp

清單 16. Timestamp 類型轉碼

dojo.declare("MyTimestampTextBox",[dijit.form.TimeTextBox], { 
  serialize: function(d, options) { 
    return dojo.date.locale.format( 
      d, {selector:'datetime', 
        datePattern:'yyyy-MM-dd', 
        timePattern:'HH:mm:ss'}).toLowerCase() + ".000000"; 
  } 
 });

  說明:定義自己的 dojo Timestamp 控制項,需要繼承 dijit.form.TimeTextBox (Dojo 中預設的 Time 控制項
); 重載 dijit.form.TimeTextBox 中的 serialize 方法 : 指定當前控制項的類型為 datetime (selector: ’
datetime ’), 將控制項中的 Timestamp 值轉成 yyyy-MM-dd HH:mm:ss.SSSSSS 格式 , 本例中將最後的六位微秒統一置為
0, 因為在平時的應用中基本不會使用到後面的微秒,當然也可以根據實際的需要置成不同的值。

  總結

  Dojo 是一個功能豐富,易於擴充的 JavaScript 工具包,同時提供了物件導向的編程模式。本文主要介紹了 dijit
包下的日期控制項,對其架構結構,使用方式,擴充點都作了詳細介紹。通過本文的學習相信可以使您在項目中熟練的使用 dojo 日期控制項,同時在學習使用其他 dojo
控制項時,也為您提供了很好的學習思路

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.