內容概述
本系列“vue專案中使用bpmn-xxxx”分為七篇,均為自己使用過程中用到的例項,手工原創,目前陸續更新中。主要包括vue專案中bpmn使用例項、應用技巧、基本知識點總結和需要注意事項,具有一定的參考價值,需要的朋友可以參考一下。如果轉載或通過爬蟲直接爬的,格式特別醜,請來原創看:我是作者原文
前情提要
前面我們討論了bpmn流程圖的基本繪製、新增節點顏色等,本次我們來說,如何把xml檔案中各種標籤包裹的節點屬性,轉成前端常用的json格式,方便回顯在頁面。首先,我們通過一張圖看一下流程圖xml檔案中,節點的屬性有哪幾種格式。
思路分析
可以看到,節點的屬性被包含在<bpmn:extensionElements>下的<camunda:inputOutput>標籤下,下一層的每個 <camunda:inputParameter>都是一個屬性,屬性共分為三總格式
- <camunda:inputParameter>標籤下沒有子元素
它的屬性“name”便是節點的屬性名,標籤中值“少年的你”便是節點屬性值。所以我們得到的第一個屬性為“selfName:少年的你“ - <camunda:inputParameter>下有子元素
2.1 子元素為<camunda:map>,map在後端語言裡相當於前端的物件(object),對,沒有錯,這個<camunda:map>標籤表示的就是物件。它的下一級標籤<camunda:entry>表示物件下的各個鍵值對。key是鍵名,標籤值是屬性值。所以,根據<camunda:map>標籤,我們得到節點的第二個屬性:nodeDesc: { class: '一年一班',age: '8'},看來這個節點是個剛上一年級的8歲小朋友。
2.2 子元素為<camunda:list>,根據2.1的判斷,聰明的你可能猜到了,list表示的是陣列。陣列沒有鍵值對,所以它下面的<camunda:value>表示陣列的其中一 項。所以,我們得到節點的第三個屬性:interestFood: ['蘋果', '香蕉', '西瓜']。所以,根據這一段xml,我們希望的是,能把它解析成一段前端js讀懂的json資料,例如:
- <camunda:inputParameter>標籤下沒有子元素
form:{ selfName:少年的你, nodeDesc: { class: '一年一班', age: '8' }, interestFood: ['蘋果', '香蕉', '西瓜'] }
有了這段json,我們就可以將節點屬性以想要的形式,展示在流程圖的外面了。那麼,開動吧~~~
程式碼實現
注意,雖然流程圖檔案是一段xml檔案,但是我們不採用直接讀xml檔案的方式去解析,因為bpmn的element下,為我們提供了“businessObject“,這是個萬能的小可愛,它裡面包含節點的所有資訊。那麼怎樣拿到節點例項element呢,在第二篇中,我們講到拿到節點例項有兩種方式,1是點選事件獲取,2是根據id。此時我們採取第一種,即當點選每個節點時,我們可以拿到e,e.element.businessObject 就是我們想要。
addEventBusListener() { let eventBus = this.bpmnModeler.get('eventBus'); // 註冊節點事件,eventTypes中可以寫多個事件 let eventTypes = ['element.click']; eventTypes.forEach((eventType) => { eventBus.on(eventType, (e) => { let {element} = e; if (!element.parent) return; if (!e || element.type === 'bpmn:Process') { return false; } else { if (eventType === 'element.click') { let businessObject = element.businessObject || element; // 此時的businessObject 是我們想要的萬能的小可愛 this.splitBusiness2Json(businessObject); } } }); }); }
拿到businessObject,接下來我們要去拆分它,將屬性轉成json。根據上面的分析,我們已經知道了屬性的三種形式,那麼直接上程式碼吧,splitBusiness2Json是主要方法:
splitBusiness2Json(businessObject) { let formData = {}; let params = this.getExtensionElement(businessObject, 'camunda:InputOutput'); if (params && params.inputParameters) { params.inputParameters.forEach((item) => { let definition = item.definition; if (definition) { if (definition.$type === 'camunda:List') { let arr = []; definition.items.forEach((itemsItem) => { arr.push(itemsItem.value); }); formData[item.name] = arr; } else if (definition.$type === 'camunda:Map') { let obj = {}; if (definition.entries) { definition.entries.forEach((entriesItem) => { obj[entriesItem.key] = entriesItem.value; }); formData[item.name] = obj; } } } else { formData[item.name] = item.value; } }); } this.form = formData; console.log('this.form', this.form); }
getExtensionElement:獲取extensionElement下所有的屬性
getExtensionElement(element, type) { if (!element.extensionElements) { return; } return element.extensionElements.values.filter((extensionElement) => { return extensionElement.$instanceOf(type); })[0]; }
成果驗證
此時,我列印一下this.form,格式如下:
bingo~格式和我們開篇時分析的完全相同,說明我們的函式成功了。此時可以把屬性顯示在需要的地方了。
我猜,此時你肯定有一個想法,既然屬性可以轉成json展示, 那如果在上圖的表單裡對屬性進行修改,可以將修改得值寫回到xml中,儲存到後端嗎?當然可以,下一篇,我們來說json轉換為流程圖xml。
進行到現在,我們已經實現了將xml中的屬性轉化為json了,完整程式碼是個資料夾,不知道怎樣傳到部落格裡。所以,想要獲取完整程式碼的小夥伴, 可以公眾號聯絡我,掃下面二維碼或公眾號搜“Lemoncool”,即可獲取~