iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 12
1
Modern Web

從零開始的個人化記帳程式開發系列 第 12

記帳程式 (12):關於網站中共用 dialog 的資料流處理

遇到的問題

目前的進度在做記帳程式「支出紀錄」的增刪改查,原本以為這樣簡單的 CRUD 應該是一塊小蛋糕,卻在要將「新增」與「編輯」的 form dialog 抽成共用模組時遇到資料流的問題。

將整個記帳紀錄的操作畫個簡圖如上,這裡的目的是要將「新增」、「編輯」都能使用 BillingDialog 這個共用模組。

明明直覺是一個可以輕鬆解決的問題,但卻卡了一陣子,於是今天決定冷靜地整理關於共用對話框資料傳遞的流程。

解決的想法

其實這種共用對話框的作法有好幾種寫法,以下分別列出幾種我想到的方法。

解法一:抽成全站共用的動態模組

一種是考慮到未來全站都會有使用 dialog 的需求,所以利用 Vue 中的 動態模組(Dynamic Components) 寫法,並搭配 Vuex 的 store 存放這個 dialog 的相關資料:要顯示的模組、資料、callback function。

如此一來未來全站有任何一個地方要打開一個 dialog,只要撰寫一個特定樣貌的 dialog 並註冊在這個動態模組中,就能直接利用 store 的 action 與 state 來操作打開與關閉對話框,雖然要做比較多工,但算是比較一勞永逸的方法。

解法二:只寫成一般可重用的模組

這個解法比較直覺,以這邊的例子而言,就是直接將 BillingDialog 抽成「新增」與「編輯」的共用模組就好,也就是只要把原本搞不定的資料流,在父層的 Billing 搞定就好。

最後也是直接選擇這個做法。

解法三:放棄治療

原本想說都弄不出來的話,不如就不另外抽成模組了,「新增」用一個、「編輯」自己用一個,不過這樣比較像是在逃避問題,但不失為一個好的解法,畢竟能趕上十二點發文比較重要。

實作

在父層 Billing 的寫法如下:

<el-button
  class="pg-billing__btn-add"
  type="primary"
  @click="handleAdd"
>新增紀錄</el-button>
<BillingDialog
  :showDialog="showDialog"
  :dialogData="dialogData"
  @close="closeDialog"
/>
<BillingList @edit="handleEdit" />
data() {
  return {
    showDialog: false,
    dialogData: {
      action: '',
      data: {}
    }
  }
},
methods: {
  handleAdd() {
    this.dialogData.action = 'ADD'
    this.dialogData.data = {}
    this.showDialog = true
  },
  handleEdit({ index, data }) {
    this.dialogData.action = 'EDIT'
    this.dialogData.data = data
    this.dialogData.index = index
    this.showDialog = true
  },
  closeDialog() {
    this.dialogData.action = ''
    this.dialogData.data = {}
    this.showDialog = false
  }
}

這邊稍微筆記一下,首先在 Billing 有兩個地方會發出事件叫 BillingDialog 打開:

  • Billing 中的「新增紀錄」按鈕
  • BillingList 中每一列的「編輯」按鈕

所以分別寫 handleAddhandleEdit 的操作。而因為兩種操作的行為不一樣,需要紀錄一下是哪一種操作,這邊紀錄一個資料狀態如下:

dialogData: {
  action: '',
  data: {
    dollar: 0,
    type: '',
    account: '',
    title: ''
  }
}

這裡的 action 紀錄是 ADD 還是 EDIT,而 data 則是按編輯時要將原本當列的紀錄傳給 BillingDialog

再來還需要在 Billing 的地方紀錄 dialog 開關的狀態,這裡用 showDialog 表示。

最後還要知道 BillingDialog 什麼時候關閉對話框,所以需要一個關閉的 callback 事件,用來將 Billing 這一層 dialog 相關的資料 reset。

再來就可以處理 BillingDialog 這一層:

watch: {
  showDialog: function(newValue) {
    if (newValue) {
      this.dialogFormVisible = true
      if (this.dialogData.action === 'ADD') {
        this.form = {
          dollar: 0,
          type: '',
          title: '',
          account: ''
        }
      } else {
        this.form = { ...this.dialogData.data }
      }
    }
  }
}

若是在父層收到開關變化說要打開, dialog 這層就將自己的開關狀態打開,並根據 action 的種類準備好對應的表單資料,其他的就交給 el-dialog 處理了。

今天修正了昨天搞不定的 dialog 共用的問題,明天先來研究怎麼弄後端系統吧,不然一直在 store 弄假資料最後仍然是要改不少。

後記

紀錄一下第二個週末的有趣現象,團隊死線前衝刺有你有我真溫馨/images/emoticon/emoticon01.gif


上一篇
記帳程式 (11):基本功能開發 - 月記帳本 Part.3
下一篇
記帳程式 (13):所以我說那個 API 呢?
系列文
從零開始的個人化記帳程式開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
lb01910483
iT邦新手 5 級 ‧ 2019-09-28 23:58:44

第一種解法覺得遇到最困難的情況就會是當有需求是嵌套 dialog 的時候就會很慘了XD

ckchuang iT邦新手 4 級 ‧ 2019-09-29 00:52:27 檢舉

對啊,可能就只能先關掉原本的,有需要的話再另外記住前一個 dialog 的資料。

但假如真的遇到有嵌套 dialog 的狀況,好像轉向思考其他的呈現方式會比較好,太多層的 dialog 畫面會有點複雜。

【**此則訊息已被站方移除**】

我要留言

立即登入留言