內容概述
本系列“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了,完整代碼是個文件夾,不知道怎樣傳到博客里。所以,想要獲取完整代碼的小伙伴, 可以公粽號聯系我,掃下面二維碼或公眾號搜“前端便利貼”,即可獲取~
