基於 Angularjs&Node.js 雲編輯器架構設計及開發實踐 ...
一、產品背景
產品是一個內部項目,主要是基於語義網本體的雲端編輯器,用於構建語義知識庫
。拋開語義網本體概念不談
,簡單說就是一個簡易的visual studio 雲端編輯器。而圖形顯示則是在百度腦圖的基礎上改進的,增加了自己的形狀和顏色,以及其他功能。
具體語義網、本體是什麼 (http://baike.baidu.com/link?url=6ctsNtk-dthPu-3kiKK_JdMikArIfvbD4VMAQuc685--88X4lggwo58R-q6zKAGlVUcN_RlxQRr5rlPE3B12WK)
二、總體架構
整個系統是由三層構成,分別為UI、API、Infrastructure:
UI層
UI層主要是用於用戶交互界面,目前主要是基於Web的顯示方式,未來可擴展移動app。web端採用單頁面程式,
所有數據通過ajax請求,最後通過nginx反向代理將前端站點和API站點部署在同一功能變數名稱下。
技術:Html5、Css3、Es5
框架: agularjs
API
在API層中主要提供UI端所需要的API以及對外的雲API。
技術:node.js
框架: express等
Infrastructure
基礎層主要提供知識庫相關操作,以及數據相關操作,基礎層主要是基於Apache jena(Jena是一個語義網本體框架)的封裝。以及對阿裡雲一些服務的封裝比如資料庫,緩存等。
技術: java
框架:spring spring.data jena 等
1. 前端架構
a.前端層次
前端核心功能是編輯器,由於業務複雜而多變,因此在邏輯上對前端進行了分層處理。系統由三層結構構成,
由下至上分別為infrastructure、configuration、webapp構成,每層又含有若幹模塊。
在代碼文件中app文件對應webapp層
,configuration文件對應configuration層
,lib文件對應infrastructure層
。
infrastructure層包含了系統所使用的基礎框架,包括下麵若幹框架:
- Editor: 自行開發WebIDE佈局框架,主要用於WebIDE的佈局設計等。
- Kity: 百度前端團隊的腦圖框架,主要用於類圖顯示等。
- Util: Util主要涵蓋了第三方的庫例如jQuery、bootstrap、eventbus等除Editor和Kity外其他庫均屬於Util範疇。
configuration層包含了系統所需要配置的文件,主要由以下幾個部分構成:
- MenuConfiguration: 用於應用程式頂部菜單和右鍵菜單的配置。
- FileConfiguration: 用於對編輯器所支持的文件配置。
- ServiceConfiguration: 用於伺服器端請求配置。
- Theme: 定義了系統基本皮膚和皮膚擴展。
webapp層包含了界面顯示的頁面模塊均為單頁面程式:
- UserDashboard: 用戶工作台入口,管理項目,新增項目等。
- EditSpace: 編輯器工作區。
b.核心基礎模塊設計
Edtior:是編輯器的功能基礎,用於控制編輯器視窗佈局、分割、樣式等,主要包括三個核心類:
- Editor: 每個編輯器只有一個Editor對象,是編輯器的基礎對象,其他對象都可以組合至Editor對象中。
- Tabcontainer:Tabcontainer對象是editor下的一個區域對象,用於控制佈局、定位、顯示、變化等特性,在Editor中可以有多個Tabcontainer。
- Panel:Panel對象是Tabcontainer下的一個內容對象,用於控制內容,一個Tabcontainer下可以有多個Panel實現對選項卡效果。
var Editor = require('/lib/editor-ui/src/editor/editor');
var editorUi = new Editor('#container');
editorUi.init('Split5');
// region top
console.log(editorUi.getTabContainer('split5-top').getSize());
module.exports = window.editorUi = editorUi;
var Panel = require('/lib/editor-ui/src/panel/panel');
var containerTop = editorUi.getTabContainer('split5-top');
containerTop.isTabCard = false;
containerTop.addPanel(new Panel({name: '點擊我隱藏', template: editSpaceTemplateConfiguration.toolBarTemplate}));
// endregion
// region left
var containerLeft = editorUi.getTabContainer('split5-bottom-left');
containerLeft.direction = 'left';
containerLeft.addPanel(new Panel({name: 'left點擊我隱藏', templateHtml: 'left我是內容'}));
containerLeft.addPanel(new Panel({name: 'left點擊我隱藏1', templateHtml: 'left我是內容1'}));
containerLeft.addPanel(new Panel({name: 'left點擊我隱藏2', templateHtml: 'left我是內容2'}));
MenuConfiguration:用於應用程式頂部菜單和右鍵菜單的配置,由於菜單功能複雜多變因此採用配置結構。其中頂部工具欄菜單最為複雜,因為根據選中內容不同,需要動態隱藏或顯示。我們採用了管道式處理方式,執行邏輯雙擊或 單擊界面上的任何元素激發依次管道過濾,在管道過濾中每個按鈕維護自己的過濾邏輯返回bool值告訴是否通過過濾
。
{
"name": "新建本體",
"cssClass": "kop-tool-bar-ontology",
"disabledCssClass": "kop-tool-bar-ontology-disabled-icon",
"commandName": "toolbar/ontology/new",
"enableHandler": "newOntologyEnableHandler",
"children": []
}
渲染按鈕 的步驟如下:
- 獲取菜單中當前類型需要顯示的按鈕。
- 根據按鈕的類型圖標等顯示按鈕。
動態改變按鈕 (在選中文件或元素不同時按鈕會呈現可用和不可用狀態) 的步驟如下:
- 雙擊或單擊事件激活過濾管道
- 執行按鈕數組中所有enableHandler方法。
- 返回為false時發起一個buttonstatusChanges事件。
- 菜單controller接受此事件改變按鈕數據,最終改變界面元素(雙向綁定)。
除此之外還包括FileConfiguration
和ServiceConfiguration
,用於文件顯示圖標和右鍵菜單的配置
var fileConfiguration =[{
"type":"owl", //文件類型
"iconSkin":"/asset/img/ico.jpg"
},...]
var serviceConfiguration = {
"host": "http://dev.onteditor.ad.6starhome.com/api/"
}
c.業務模塊設計
EditSpace是編輯器業務模塊,由以下幾個子模塊構成,每個模塊在項目初始化時通過調用editor框架將模版註入至頁面中:
- 頭部(Headbar)
- 工具欄(Toolbar)
- 項目區(ProjectWindows)
- 導入區(ExportWindows)
- 設計區(DesignWindows)
- 屬性區(PropertyWindows)
- 編輯區(EditWindows)
- 狀態欄(StatusBar)
在系統初始化時候加入各種模塊
var Panel = KOP.EditorUI.Panel;
var TabContainer = KOP.EditorUI.TabContainer;
// endregion
// region 左邊框初始大小,禁用選中效果
var leftSpace = editorUi.getTabContainer('split8-main-space-wrap');
leftSpace.getObject().width(300);
editorUi.getTabContainer('split8-main-space-edit').getObject().height(250);
// region 頭部模版註入
var headBarContainer = editorUi.getTabContainer('split8-top');
headBarContainer.addPanel(new Panel({template: editSpaceTemplateConfiguration.headBarTemplate}));
在每個模塊中包含了單元測試(test)
事件處理中心(event-handler)
界面(html)
控制器(controller)
如下圖所示:
事件處理中心接受全局的事件,比如之前配置好的按鈕的事件,其他模塊與之通信的事件,均是在事件模塊中處理。
function onNewClass($scope) {
$scope.$on('toolbar/class/new', function (e, param) {
});
}
2. Node.js端設計
Nodejs端主要是對各種業務的組裝,通過express框架暴露RestfulAPI,這裡不再贅述。
三、單元測試
可參看之前文章 http://www.cnblogs.com/vipyoumay/p/5331787.html
四、持續集成及自動部署
- 代碼管理: gitlab(本地部署)
- CI伺服器: jenkins(本地部署)
- 構建部署:docker(本地部署)
整個配置太多了就不講解了,有需要可以留言
五、打包
採用grunt對前端打包,如何打包請自行百度。
六、總結
整個項目工作量很大,我們團隊6人,在規定時間內(包括需求設計一共3個月)完成,持續集成自動化部署給我們節約了很多時間,
另外另外架構的設計也為我們在需求微調贏的了時間。
設計包括的內容很多,這裡不能一一說完,如果有興趣可評論或私信交流。