簡介
一個菜單有多個菜單項,一個列表有多個列表項,這是一類控件包含多個相同子項場景。這類控件有很多共有的特性,所以我們需要進行抽象和總結,來形成統一的功能和接口。根據子項的實現方式我們分為2種:
- 子項實現為子控件
- 子項僅作為控件的DOM片段
這2種實現方式的主要差別在於:
- 渲染DOM方面,
1) 子項實現為控件,渲染DOM的邏輯是獨立的,不受父控件控制的
2) DOM片段,需要控件處理所有的子項的渲染邏輯
2. 狀態改變和事件觸發方面:
1) 子項實現為控件,狀態的改變邏輯和事件觸發由子控件處理,如果影響到其他的子控件,由父控件統一處理,例如選中一項時,父類會清理其他選中的子控件的選中狀態。
2) DOM片段,的所有狀態、事件觸發都由包含這些DOM片段的控件來處理。
3. 選項的增刪改方面
選項在增刪改時,都需要在包含這些項的控件上做統一的處理。
4. 可復用性方面
1) 子項實現為控件,可以用於其他控件中,作為其他控件的子項,例如一個按鈕分組包含多個按鈕,一個工具欄也可以包括多個按鈕。
2) 而DOM片段,只能在包含項的控件中實現,作為折中的方案,可以創建一個基類,其他控件實現這個基類即可。
5. 性能方面
1) 子項實現為控件,在生成的效率方面有很大的問題,控件的生成開銷遠遠大於DOM片段的開銷。
2) 事件處理方面,DOM片段可以用委托(delegate)的方式,統一處理子項的事件,可以不考慮子項的增刪給控件帶來的開銷;子控件的方式必須自己觸發事件,往上冒泡到父控件,統一處理
控件集合
一般的菜單、列表、tab、工具欄等控件的子項都是單獨的子控件,我們可以抽取出一個擴展 ControlCollection 來實現子控件的共有的功能:
- 增刪改
- 迭代,可以參考 .net 中 Enumerate的實現來提供接口
- 選中,在前面的文章中已經詳細的介紹過選中
- 鍵盤處理
在實踐中控件的嵌套需要處理一些問題:
- 子控件的默認配置,可以在父控件上統一配置子控件的默認選項,例如模板、選中狀態使用的樣式、出錯顯示的信息等等。
- 子控件之間的通信,有些子控件的狀態改變會引起其他子控件的變化,例如單選,選中一個子控件時,需要清理其他子控件上的選中狀態。
簡單列表
我們把將子項實現為DOM片段的的控件的基類定義為簡單列表,常用於需要顯示大量數據的場景,例如 grid或者顯示大量數據的list。我們需要在這種控件中實現:
- 數據源:所有的增刪改、排序等數據操作,都通過數據源來處理,不直接操縱DOM片段
- 數據源綁定:理數據源加載、出錯、增刪改記錄后,控件的DOM 隨之變化
- 鍵盤事件處理
其實就是使用MVC的方式,把數據源和展示方式分離開來,所有選項的操作都是通過數據源的接口來實現。
Grid的操作最能體現出數據源操作數據的好處,查看示例
實現