昨天先引入了 Day.js
後,接下來要繼續完成選取月曆上日期時,要對應到該日記帳清單的增刪改查。
首先要來重新回憶一下當初這個 component 是怎麼做的,一看不得了,這個 Calendar 原本要傳入選定的日期,以今天的日期 2019-10-11
為例,要這樣傳進去:
{
year: 2019,
month: 9,
day: 11
}
日期是傳物件就算了,但月份的部分竟然還要另外減一。
是我。
於是將原本的元件改造一下,改為將選定的日期傳出來就好,不餵入其他 props
,但回傳的日期格式有點偷懶就先沒動了。
接著要開始將所有元件串接上月曆了,這邊稍微畫個圖,看看整體開發完後,各個元件的關係及資料流會清楚一點:
還是我。
開發完成後一直覺得資料流好像可以再優化,圖畫完後可以更容易看清楚問題在哪,像是 BillingCalendar
這一層有點多餘,並且將一些共用資料放在 store 用 mapState
直接對,會比放在 Billing
資料一定要透過父層傳來傳去更方便。
於是不偷懶的調整成下面這樣:
稍微乾淨一點了,果然開始動手打程式前不思考就直接寫,會很容易寫出爛 code。以下先解釋一下每個角色分別是畫面上哪一個部分:
Billing
:是整個月記帳本的最外層頁面,其中內容切為三個子元件
Calendar
:月曆元件。BillingList
:記帳紀錄列表。BillingDialog
:新增與編輯的表單對話框。Store
:這裡指 billing 的 store module,負責儲存資料並且與後端溝通。FireStore
:後端 API server 與資料庫。當使用者點擊畫面上的月曆選定日期時,會觸發 Calendar
中的 select
事件往上傳給 Billing
。
當 Billing
收到新的日期時,本身的事件處理也會觸發去執行呼叫 action,去重讀當日的記帳紀錄:
handleSelectedDate(date) {
// 處理 Calendar 回傳的日期格式
const { year, month, day } = date
const zMonth = ('0' + (month + 1)).slice(-2)
const zDay = ('0' + day).slice(-2)
this.selectedDate = `${year}-${zMonth}-${zDay}`
// 重拉資料
this.isLoading = true
this.$store
.dispatch('billing/getExpenseData', date)
.then(() => {
this.isLoading = false
})
.catch(status => console.log(status))
}
當資料回來後會更新 store 的 expenseData
,這時候 BillingList
就會收到新的資料而自動更新畫面。
由於原本之前開發時,還沒有加上日期的欄位,所以調整資料結構花了一番功夫。
而新增的部分遇到一個比較算是操作流程的問題,因為按下新增時會跳出一個 dialog,裡面可以選擇要紀錄這一筆帳的日期。
那假如今天我的月曆點在 10/11 的地方按新增,然後新增日期選擇 10/12,依照原本的邏輯,儲存後記帳資料更新會顯現 10/12 的資料,但我的月曆卻仍選在 10/11 上面,而造成兩者不對應的問題。
想到的解法有兩種:
後來偷懶選擇第二種,變成是根據月曆選定的日期,只做那一天的操作與重載資料,體驗沒那麼好但開發相對單純。
這邊比較值得紀錄的是現在新增、編輯、刪除後,要重新拉回特定日期的資料,那這個要怎麼修改 API 呢?
查了一下語法,Firestore 的讀取有提供一個 where
的寫法,其實就像 SQL 語法中的篩選條件一樣:
db.collection('expense')
.where('date', '==', date)
.get()
.then(querySnapshot => {
const documents = querySnapshot.docs.map(doc => {
return {
...doc.data(),
id: doc.id
}
})
commit('SET_EXPENSE_DATA', documents)
resolve()
})
在原本讀取集合中的文件資料後,加上 where('date', '==', date)
,就能夠去直接拉取文件中欄位 date
與我指定的日期一致的資料,非常方便吧!
今天花了一番功夫將月曆選擇對應記帳資訊的功能串起來了,也總算完成一個基本功能了。
雖然只有支出的部分,這部分要完整還有「支出、收入、轉帳共用表單」、「分類管理」的功能還沒做,真覺得當初前面怎麼有勇氣列這麼多開發功能 XD
我們明天見~
不是都是先寫了再說嘛XD
寫了才知道原來寫這麼爛
還是因為我太菜QQ
因為好像常聽別人在教學時說:「別急著寫程式,先思考清楚如何拆解問題及設計資料結構後再下手。」
但算是有時候為了求快的確都是先寫了再說,先求有再求好也是一種開發方式,然後就會容易產出一堆爛 code