全網最詳bpmn.js教材-http請求篇

前言

Q: bpmn.js是什麼? 🤔️javascript

bpmn.js是一個BPMN2.0渲染工具包和web建模器, 使得畫流程圖的功能在前端來完成.前端

Q: 我爲何要寫該系列的教材? 🤔️vue

由於公司業務的須要於是要在項目中使用到bpmn.js,可是因爲bpmn.js的開發者是國外友人, 所以國內對這方面的教材不多, 也沒有詳細的文檔. 因此不少使用方式不少坑都得本身去找.在將其琢磨完以後, 決定寫一系列關於它的教材來幫助更多bpmn.js的使用者或者是期於找到一種好的繪製流程圖的開發者. 同時也是本身對其的一種鞏固.java

因爲是系列的文章, 因此更新的可能會比較頻繁, 您要是無心間刷到了且不是您所須要的還請諒解😊.ios

不求贊👍不求心❤️. 只但願能對你有一點小小的幫助.git

http請求篇

上一章節咱們介紹了bpmn.js的一些基礎知識點以及介紹了在vue是如何使用的, 要是對bpmn.js不瞭解的小夥請移步:github

這一章節主要講解的是關於bpmn.js如何與後臺進行交互的問題, 經過學習此章節你能夠學習到:web

經過http請求獲取數據並渲染npm

將編輯以後的最新bpmn發送給後臺canvas

編輯完保存爲bpmn文件或svg文件

經過http請求獲取數據並渲染

在以前的案例中使用的一直都是本地寫死的一個xml字符串, 那麼實際使用上確定不會以這種方式.

咱們團隊如今採用的作法是:

  • 前端發起請求, 獲取到一個bpmn文件的地址
  • 拿到地址以後, 使用axios請求這個地址獲得xml的字符串(這裏命名爲bpmnXmlStr)
  • 使用importXML方法將字符串轉化爲圖形並渲染.

爲了模擬上面的執行環境我接着上一章節的項目案例bpmn-vue-basic在components文件夾下建立一個axios.vue的 文件並配置好路由:

const routes = [
	...
	{
		path: '/axios',
		component: () => import('./../components/axios')
	}
]
複製代碼

同時在項目中安裝axios以用於前端發送http請求:

npm i axios --save-D
複製代碼

首先在HTML代碼中做出一個loading的效果, 用戶前端在獲取到xml以前的一個展現:

// axios.vue
<template>
  <div class="containers">
    <div class="loading" v-if="loading">
        Loading...
    </div>
    <template v-else>
        <div class="canvas" ref="canvas"></div>
        <div id="js-properties-panel" class="panel"></div>
    </template>
  </div>
</template>
複製代碼

而後在js中引入axios並定義一個getXmlUrl方法模擬獲取bpmn文件地址:

// axios.vue
<script>
...
import axios from 'axios'
import { xmlStr } from '../mock/xmlStr' // 引入一個本地的xml字符串, 如果沒有獲取到後臺的數據則用它

export default {
	...
	data () {
	   return {
		...
		loading: true,
        xmlUrl: '',
        defaultXmlStr: xmlStr
		}
	},
	methods: {
  	async init () {
      this.loading = true
      this.xmlUrl = await this.getXmlUrl()
      console.log(this.xmlUrl)
      this.loading = false
      this.$nextTick(() => { // 等待 DOM 更新以後再對工做流進行初始化
      	this.initBpmn()
    	})
    },
    getXmlUrl () { // 該方法模擬請求後臺獲取bpmn文件地址
        return new Promise(resolve => {
            setTimeout(() => {
                const url = 'https://hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/bpmnMock.bpmn' // 模擬網絡請求的一個地址
                resolve(url)
            }, 1000)
        })
    },
    initBpmn () {
      ... // 這裏是初始化工做流的代碼
      this.createNewDiagram()
    },
    async createNewDiagram () {
        const that = this
        let bpmnXmlStr = ''
        if (this.xmlUrl === '') { // 如果後臺沒有數據則使用默認的一個xml
            bpmnXmlStr = this.defaultXmlStr
            this.transformCanvas(bpmnXmlStr)
        } else {
            let res = await axios({
                method: 'get',
                timeout: 120000,
                url: that.xmlUrl,
                headers: { 'Content-Type': 'multipart/form-data' }
            })
            console.log(res)
            bpmnXmlStr = res['data']
            this.transformCanvas(bpmnXmlStr)
        }
    },
    transformCanvas(bpmnXmlStr) {
      // 將字符串轉換成圖顯示出來
      this.bpmnModeler.importXML(bpmnXmlStr, (err) => {
        if (err) {
          console.error(err)
        } else {
          this.success()
        }
        // 讓圖能自適應屏幕
        var canvas = this.bpmnModeler.get('canvas')
        canvas.zoom('fit-viewport')
      })
    },
    success () {
        console.log('建立成功!')
    }
    }
}
</script>
複製代碼

你能夠直接用我在案例中模擬獲取地址的那個路徑:

hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/bpmnMock.bp…

案例Git地址: LinDaiDai-bpmn.js測試案例axios.vue

將編輯以後的最新bpmn發送給後臺

上面咱們介紹瞭如何從後臺那裏拿到數據並渲染到頁面上, 但這樣是不夠的.

可能你須要將編輯以後的最新bpmn存儲到後臺.

該功能就涉及到了bpmn.js中的事件綁定, 也就是前端須要給圖形綁定一個事件來檢測到圖形的改變, 並獲取到最新的xml 信息.

新建一個save.vue文件並將axios.vue裏的內容複製進來.

success()方法中添加一個addBpmnListener()綁定事件的方法:

// save.vue
<script>
   success () {
    	console.log('建立成功!')
    	this.addBpmnListener()
  	},
		// 添加綁定事件
    addBpmnListener () {
      const that = this
      // 給圖綁定事件,當圖有發生改變就會觸發這個事件
      this.bpmnModeler.on('commandStack.changed', function () {
        that.saveDiagram(function(err, xml) {
          console.log(xml) // 這裏獲取到的就是最新的xml信息
        })
      })
    },
    // 下載爲bpmn格式,done是個函數,調用的時候傳入的
    saveDiagram(done) {
      // 把傳入的done再傳給bpmn原型的saveXML函數調用
      this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
        done(err, xml)
      })
    }
</script>

複製代碼

如圖所示:

img2

案例Git地址: LinDaiDai-bpmn.js測試案例save.vue

編輯完保存爲bpmn文件或svg文件

在上面咱們監聽commandStack.changed事件就能實時獲取到最新的xml信息.

拿到這些信息以後你能夠選擇在每次圖形改變的時候就請求給後臺傳遞給他們最新的xml;

也能夠選擇將其保存到一個變量中, 而後在頁面中給一個保存按鈕, 當點擊按鈕的時候再傳遞給後臺.

或許你可能徹底不須要再請求給後臺, 而是但願本地就可以下載爲bpmn文件或者svg文件.

在上面save.vue案例的基礎上增長兩個保存按鈕:

img3

而後修改HTML代碼:

// save.vue
<template>
	...
	<ul class="buttons">
    <li>
    	<a ref="saveDiagram" href="javascript:" title="保存爲bpmn">保存爲bpmn</a>
    </li>
    <li>
    	<a ref="saveSvg" href="javascript:" title="保存爲svg">保存爲svg</a>
    </li>
  </ul>
</template>
複製代碼

js代碼中加上:

// save.vue
<script>
	...
  addBpmnListener () {
      const that = this
      // 獲取a標籤dom節點
      const downloadLink = this.$refs.saveDiagram
      const downloadSvgLink = this.$refs.saveSvg
        // 給圖綁定事件,當圖有發生改變就會觸發這個事件
      this.bpmnModeler.on('commandStack.changed', function () {
        that.saveSVG(function(err, svg) {
            that.setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg)
        })
        that.saveDiagram(function(err, xml) {
            that.setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml)
        })
      })
  },
  // 下載爲SVG格式,done是個函數,調用的時候傳入的
  saveSVG(done) {
      // 把傳入的done再傳給bpmn原型的saveSVG函數調用
      this.bpmnModeler.saveSVG(done)
  },
  // 下載爲bpmn格式,done是個函數,調用的時候傳入的
  saveDiagram(done) {
      // 把傳入的done再傳給bpmn原型的saveXML函數調用
      this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
          done(err, xml)
      })
  },
  // 當圖發生改變的時候會調用這個函數,這個data就是圖的xml
  setEncoded(link, name, data) {
      // 把xml轉換爲URI,下載要用到的
      const encodedData = encodeURIComponent(data)
      // 下載圖的具體操做,改變a的屬性,className令a標籤可點擊,href令能下載,download是下載的文件的名字
      console.log(link, name, data)
      let xmlFile = new File([data], 'test.bpmn')
      console.log(xmlFile)
      if (data) {
        link.className = 'active'
        link.href = 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData
        link.download = name
      }
  }
</script>
複製代碼

案例Git地址: LinDaiDai-bpmn.js測試案例save.vue

後語

系列相關推薦

《全網最詳bpmn.js教材-基礎篇》

《全網最詳bpmn.js教材-事件篇》

相關文章
相關標籤/搜索