將 Flex 應用程式與 IBM Mashup Center 整合

genusBIT發表於2009-06-08

IBM Mashup Center 提供了很多可用於構建 mashup 應用程式的即用型小部件。使用這些小部件可以在網格、線形圖甚至地圖上顯示資料。有時候,需要對圖形使用者介面(GUI)的顯示進行更多的定製,而已有小部件 中可用的設定還不夠。

有多種方式可以開發自己定製的小部件。IBM Mashup Center 附帶有 Lotus Widget Factory,這是一個很棒的 GUI 工具,通過它無需編寫程式碼就可以開發定製的小部件。如果您熟悉 JavaScript、Dojo 或其他程式語言,那麼可以根據 iWidget 規範通過編寫程式碼開發定製的小部件。iWidget 框架非常靈活,它允許與其他技術無縫整合。在本文中,學習如何將 Adobe Flex 應用程式與 IBM Mashup Center 整合,從而顯著增強 mashup 的威力。

您應該對 iWidget 框架和 Adobe Flex 程式設計有基本的認識。

Flex 應用程式概述

Flex 是用於構建富 Internet 應用程式的一個流行的開源框架,可以使用 Adobe Flash Player 在大多數瀏覽器中執行這些應用程式。Flex 提供很多 GUI 介面元件。圖 1 顯示一個示例 Flex 儀表板應用程式,其中有互動式和動畫效果的圖表。


圖 1. Flex 銷售儀表板演示
Flex 銷售儀表板演示

要在瀏覽器中執行 Flex 應用程式,只需將一個 object 標記嵌入到 HTML 頁面中。這個標記用於裝載 Flash 播放器,並傳入適當的引數。清單 1 是指令碼的一個例子。


清單 1. 將 object 標記嵌入到 HTML 頁面中



	
	
	
	

	<embed>


可以在 Adobe 站點 上了解更多關於 Flex 的資訊。

Flex 應用程式開發環境

Adobe 為開發 Flex 應用程式提供了很多不同的工具。Flex Builder 是一個基於 Eclipse 的 IDE,它提供了很多很棒的特性,例如程式碼完成、分步除錯和視覺化佈局的拖放設計。另外還有一個免費的 SDK 可以作為商業的 Flex Builder 的替代品。請訪問 Adobe 站點,瞭解更多關於 Adobe 工具 的詳細資訊。


開發 Lotus Mashups iWidgets

IBM Mashup Center wiki 提供了關於小部件開發的一些有用的資訊。

對於不熟悉 iWidgets 的開發人員,這個演示 是最好的入門點。

對 iWidget 開發的詳細描述超出了本文的範圍,但我們還是回顧一下 iWidget 中和 Flex 應用程式整合相關的一些關鍵元件:widget 定義 XML 檔案和小部件 JavaScript. 類檔案。

Widget 定義 XML 檔案

該檔案有以下用途:

  • 指定 JavaScript. 類檔案:

  • 定義小部件應該釋出的事件。清單 2 顯示該小部件釋出一個名為 sendData 的事件。


清單 2. 定義小部件釋出的事件

 
 

  • 定義小部件應該處理的事件,以及收到事件時呼叫的方法。清單 3 顯示該小部件可以接收名為 receiveData 的事件,收到這種事件時會觸發函式 handleData。


清單 3. 定義小部件處理的事件

  
      


  • 定義小部件在 view 模式下顯示的內容。這是在 mashup 頁面上裝載小部件時顯示的主介面。在這個例子中,如清單 4 所示,小部件的檢視中有一個
    標記,其中顯示 “Hello”。在執行時,可以使用 JavaScript. 操縱該標記的內部 HTML 程式碼,以顯示其他內容。


    清單 4. 定義 view 模式下的內容

    
       
             Hello.
           
       ]]>
    
    

    • 定義小部件在 edit 模式下顯示的內容或小部件的設定。settings 標記通常包含一些 HTML 輸入元素,以便使用者輸入一些值,另外它還包括一個 save 和 cancel 按鈕,如清單 5 所示。


    清單 5. edit 模式中的 settings 標記

    
        
            
    Settings 1:
    Settings 2:
    ]]>

    Widget JavaScript. 類檔案

    該檔案包含小部件物件的實現。該檔案中的程式碼負責在初次裝載小部件時初始化小部件,併發布和處理事件,以便與其他小部件通訊。

    在 Lotus Mashup 中執行簡單的 Flex 應用程式

    如前所述,只需在 HTML 頁面中新增一個 object 標記,就可以將 Flex 應用程式嵌入到 Web 頁面中。IBM Mashup Center 提供了一個即用型小部件,用於將 HTML 片段嵌入 mashup 頁面。

    遵循以下步驟:

    1. 在 Tools 下找到小部件,將它拖放到畫布上。如圖 2 所示。



      圖 2. 新增 HTML Markup 小部件
      新增 HTML Markup 小部件

    2. 編輯設定,並貼上 Flex 應用程式的 Flex 應用程式指令碼標記,如圖 3 所示。



      圖 3. 設定 HTML Markup 小部件
      設定 HTML Markup 小部件

    3. 單擊 Save。Flex 應用程式在 mashup 頁面上執行,如圖 4 所示。



      圖 4. 在 HTML Markup 小部件中執行 Flex 應用程式
      在 HTML Markup 小部件中執行 Flex 應用程式

    能用這種方法顯示 Flex 應用程式是件很棒的事情。但是,要真正與 Lotus Mashups 整合,這些應用程式必須能夠與其他 iWidget 通訊。本文後面將討論設定 Flex 應用程式與其他 iWidget 之間的通訊框架的架構。

    將 Flex 應用程式與 Lotus Mashups 整合

    要將 Flex 與 Lotus Mashup 整合,關鍵的思想是構建一個包裝器 Lotus Mashup iWidget。這個包裝器 iWidget 有三個作用:

    • 顯示 Flex 應用程式的使用者介面。
    • 釋出 iWidget 事件。當 Flex 應用程式需要傳送事件時,Flex 應用程式首先將資料傳送到這個包裝器 iWidget,然後,包裝器 iWidget 將真正的事件和資料釋出到其他 iWidget。
    • 處理 iWidget 事件。當其他 iWidget 需要傳送事件到 Flex 應用程式時,包裝器 iWidget 首先處理事件。然後,包裝器 iWidget 將資料轉發到 Flex 應用程式以作進一步的處理。

    本文的下載小節提供了一個示例 Flex 應用程式和相應的包裝器 iWidget。這個 Flex 應用程式包含具有預先裝載的資料的資料網格。我們展示如何通過釋出和接收事件,將這個 Flex 應用程式與其他 iWidget 連線。通過這個包裝器 iWidget,可以將 Flex 應用程式中選擇的資料傳送到另一個 iWidget。同樣,還可以使用其他 iWidgets 將行新增到這個 Flex 應用程式中。

    檔案 FlexDataGridSample.mxml 包含 Flex 應用程式程式碼;如圖 5 所示。檔案 FlexWrapper.war 包含 iWidget 和 Flex 應用程式二進位制檔案。這個小部件可以像常規的 iWidget 一樣部署到 Mashup Center 上。將小部件上傳並新增到 Lotus Mashup 頁面上之後,編輯該小部件的設定。對於 Flex 應用程式 URL 引數,值應該為:

    http://[yourserver:port]/widgets/FlexWrapper/FlexDataGridSample.swf

    圖 5. 設定示例 Flex 包裝器 iWidget
    設定示例 Flex 包裝器 iWidget

    接下來的小節介紹示例小部件的一些重要部分,以展示如何整合這個包裝器 iWidget 和 Flex 應用程式。

    在包裝器小部件中顯示 Flex 應用程式

    為了顯示 Flex 應用程式,將 object 標記插入到小部件的檢視中。在包裝器 iWidget 的定義檔案 FlexWrapper.xml 中,已經定義了 view 區段包含一個簡單的 div 標記,作為 Flex 應用程式的佔位符,如清單 6 所示。


    清單 6. 定義 view 區段

    
       
           
       ]]>
    
    

    在執行時,包裝器 iWidget 構造裝載 Flex 應用程式的 object 標記。可以通過檢視 FlexWrapper.js 檔案中的 onview 函式,瞭解這個標記是如何構造的。這個標記需要很多引數。大多數值可以硬編碼,還有一些值應該由使用者提供,或者在執行時自動生成。例如,小部件包裝器可以允許使用者傳入 Flex 應用程式的名稱,Flash 檔案的位置,以及這個小部件的大小,如圖 5 所示。通過允許使用者傳入這些變數,可以將小部件包裝器重複用於多個 Flex 應用程式,只要這些應用程式釋出和接收相同的一組事件就行了。清單 7 中的程式碼顯示需要生成的標記的一個示例。加粗的引數必須自動生成。斜體的引數由使用者傳入,必要時也可以硬編碼。


    清單 7. 標記示例

    
    
    	
    	
    	
    	
    	
    
    	<embed>
    
    

    我們來看看必須自動生成的引數。object 標記的 id 屬性和 embed 標記的 name 屬性在整個 mashup 頁面內必須是惟一的。否則,當同一個頁面上有這個包裝器 iWidget 的多個例項時,它們之間會發生衝突。iWidget 框架為頁面上裝載的每個小部件生成一個惟一的 ID,可以通過下面的呼叫獲取這個小部件 ID:

    this.iContext.widgetId

    我們將使用這個 ID 作為 object 標記的 ID 和 name 的一部分,以確保小部件包裝器的每個例項都有一個惟一的 ID。在 Flex 包裝器的 onview 函式中可以看到,您獲取了這個小部件 ID,並將它儲存在變數 domID 中。我們將 Flex 應用程式的名稱與小部件 ID 連在一起,然後將這個字串設定為該標記的 ID 和 name:

    this.flexAppName + this.domID

    這樣一來,包裝器 iWidget 的每個例項都有一個惟一命名的標記。最後需要動態生成的引數是 FlashVars 的值。FlashVars 中定義的變數可以從 Flex 應用程式中訪問。在執行時,Flex 應用程式需要根據惟一的小部件 ID 找到包裝器 iWidget 物件的正確例項。我們將小部件 ID 儲存在一個名為 iWidgetID 的變數中,在後面的小節中,可以看到 Flex 應用程式如何獲取這個值。

    用正確的引數值構造好 object 標記後,就可以通過以下呼叫將它嵌入到 Flex 應用程式佔位符 div 標記中:

    dojo.byId(this.domID + "FlexDiv").innerHTML = flexDivHTML;

    現在,當小部件裝載並觸發 onview 函式時,它會顯示 Flash 應用程式,如圖 6 所示。


    圖 6. 在 iWidget 中顯示 Flex 介面
    在 iWidget 中顯示 Flex 介面

    將事件從 Flex 傳送到其他小部件

    Flex 中的大多數使用者介面元件都可以處理使用者事件。例如,每當使用者單擊一個特定的行時,DataGrid 元件觸發一個事件。在這個例子中,當使用者單擊一個行時,需要將選中的資料往外傳送到另一個 iWidget。要完成該任務,需要執行三個步驟:

    1. 在小部件定義 XML(見 FlexWrapper.xml 檔案)中定義一個要釋出的事件。
    2. 在包裝器 iWidget 實現中實現釋出該事件的 JavaScript. 函式。
    3. 在 Flex 應用程式中,當需要傳送事件時,呼叫該 JavaScript. 函式。

    要定義一個事件,可以像對待常規的 iWidget 一樣,將清單 8 中的程式碼片段新增到小部件定義 XML 中。


    清單 8. 定義事件

     
     
    

    釋出事件只需一行程式碼。函式 sendData 使用清單 9 中顯示的程式碼釋出事件。


    清單 9. 釋出事件

     sendData : function(data) {                    
          if(data != null){            
             this.iContext.iEvents.publishEvent("sendData", data);
          }
       }
    

    最後一步是從 Flex 應用程式中呼叫這個 sendData JavaScript. 函式。在 flex 應用程式中,首先像通常一樣定義資料網格元件的 Flex 事件處理程式。當使用者單擊一行時,函式 sendData 被呼叫:

    width="422" height="268" click="sendData()">

    在函式 sendData 中,需要找到並呼叫釋出事件的 JavaScript. 函式。如清單 10 所示。


    清單 10. 找到並呼叫 JavaScript. 函式

        public function sendData():void
        {           
          if (ExternalInterface.available) { 
         ExternalInterface.call(Application.application.parameters.iWidgetID + 
         "iContext.iScope().sendData", dgPeople.selectedItem);        
          } 
        }
    

    可以看到,只需幾行程式碼就可以觸發 JavaScript. 函式。ExternalInterface 是一個 Flex 物件,通過它可以呼叫 Flex 應用程式之外的物件。要找到適當的包裝器 iWidget,可以呼叫:

    Application.application.parameters.iWidgetID +
    "iContext.iScope().sendData"

    iWidgetID 這個值看上去是否有點熟悉?這就是在前一小節中設定的值。之前是在 FlashVars 引數中設定它,現在 Flex 應用程式可以獲取該值,並找到要呼叫的正確的函式。值 dgPeople.selectedItem 包含資料網格中被選中的行,格式為 JSON。圖 7 顯示了整個架構。


    圖 7. 通過包裝器從 Flex 釋出事件
    通過包裝器從 Flex 釋出事件

    可以將包裝器 iWidget 連線到一個常規的 Event Explorer 小部件。當使用者從 Flex Wrapper 小部件中選擇一行時,資料以 JSON 的格式被髮送到 Event Explorer,如圖 8 和圖 9 所示。


    圖 8. 將 Flex 包裝器連線到 Event Explorer
    將 Flex 包裝器連線到 Event Explorer

    圖 9. 將資料從 Flex 傳送到 Event Explorer
    將資料從 Flex 傳送到 Event Explorer

    在 Flex 中處理來自其他小部件的事件

    可以以類似的方式在 Flex 中處理 iWidgets 事件。要完成該任務,需要執行四個步驟:

    1. 定義要在包裝器 iWidget 中處理的事件。
    2. 在 Flex 應用程式中,像在任何其他 Flex 應用程式中一樣,實現一個事件處理程式。對於示例的資料網格,可建立一個名為 receiveData 的處理程式,它接收一些字串,並將一個行新增到網格中。
    3. 在 Flex 應用程式中,註冊一個回撥函式,以公佈事件處理程式 receiveData。當收到事件時,這個回撥使包裝器 iWidget 可以觸發這個函式。
    4. 在包裝器 iWidget 中實現事件處理程式,以呼叫 Flex 回撥函式。

    包裝器 iWidget 首先在 XML 實現檔案中定義它接收的事件。如清單 11 所示。


    清單 11. 定義事件

      
          
    
    

    該程式碼允許其他小部件將資料傳遞到包裝器 iWidget。當收到一個事件時,會觸發 handleData 函式(後面會實現)。

    首先需要在 Flex 中實現一個處理程式。在這個示例 Flex 資料網格中,要顯示一些僱員的姓名、職稱和年齡。這裡實現一個將一名僱員新增到列表中的處理程式,如清單 12 所示。


    清單 12. 新增一名僱員

        public function receiveData(name:String, title:String,
          age:String):void
        {
          (dgPeople.dataProvider as ArrayCollection).addItem(
              {Name: name, Title: title, Age: age});
        }
    

    清單 12 中的變數 dgPeople 是對顯示人員列表的 Flex 資料網格物件的一個引用。JavaScript. 如何觸發 Flex 函式?只需新增一個回撥。首先建立一個名為 initApp() 的函式,當 Flex 應用程式初始化時,將觸發該函式,如清單 13 所示。


    清單 13. 新增一個回撥

       
    

    在 initApp() 中,新增一個回撥,以公佈函式 receiveData,如清單 14 所示。


    清單 14. 新增一個公佈 receiveData 函式的回撥

       public function initApp():void
       {
          if (ExternalInterface.available)
            ExternalInterface.addCallback("receiveData", receiveData);  
       }
    

    最後一步是實現 iWidget 事件處理程式,以觸發 Flex 回撥。要找到 Flex 回撥,首先需要按標記名稱找到 Flex 應用程式。在 “在包裝器小部件中顯示 Flex 應用程式” 小節中,已經將 Flex 包裝器小部件標記的 ID 指定為 this.flexAppName + this.domID。這就是用於找到 Flex 應用程式的 ID。清單 15 中的程式碼找到 Flex 應用程式並觸發 receiveData 函式。


    清單 15. 找到 Flex 應用程式並觸發 receiveData 函式

        
        handleData: function(JSONpayload) { 	      
            var data = eval('(' + JSONpayload.payload + ')');    	     	    
            this.getFlexApp(this.flexAppName + this.domID).receiveData(
               data.Name, data.Title, data.Age);  
        },
        getFlexApp: function(appName) {
            if (navigator.appName.indexOf ("Microsoft") !=-1) {
                return window[appName];
            } else {
            return document[appName];
            }
        }
        

    handleData 函式被實現為處理 JSON 資料,但是可以對它進行定製,使之處理其他資料型別。圖 10 顯示了架構的輪廓。


    圖 10. 在 Flex 中處理 iWidget 事件
    在 Flex 中處理 iWidget 事件

    現在可以連線這個小部件,以處理一些事件。對於這個例子,可以使用 User Input 小部件建立一個表單,用於輸入新的僱員資料。然後,可以將輸入的值以 JSON 的格式連線到 Flex 包裝器小部件。遵循以下步驟:

    1. 從 Favorites 中拖出一個 User Input 小部件,如圖 11 所示。



      圖 11. 新增 User Input 小部件
      新增 User Input 小部件

    2. 編輯設定,新增 3 個名為 Name、Title 和 Age 的文字框,如圖 12 所示。



      圖 12. 設定 User Input 小部件
      設定 User Input 小部件

    3. 將 User Input 小部件連線到 Flex 包裝器 iWidget,如圖 13 所示。



      圖 13. 將 User Input 小部件連線到 Flex 包裝器
      將 User Input 小部件連線到 Flex 包裝器

    4. 現在小部件已連線。在 User Input 小部件中輸入新員工的姓名,單擊 Submit,新的姓名就出現在 Flex 資料網格中,如圖 14 所示。



      圖 14. 將資料從 User Input 小部件傳送到 Flex 包裝器
      將資料從 User Input 小部件傳送到 Flex 包裝器

    祝賀您!您已經成功地將一個 Flex 應用程式包裝在一個 iWidget 中,這個 Flex 應用程式現在可以釋出和處理 iWidgets 事件,並且可以與其他 iWidget 通訊。

    作者:Ronald C. Leung, 軟體工程師,Mashup Hub Enablement, IBM

    來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14751907/viewspace-605551/,如需轉載,請註明出處,否則將追究法律責任。

相關文章