列表組件概述(轉)

全文轉至:http://www.cnblogs.com/lyzg/html

此次要介紹的是列表組件。爲了寫它,我花了有將近2周的晚上,才一點一點的把它寫到如今這個程度。到目前爲止,一共寫了有17個文件,雖然沒有覆蓋到一些更復雜的場景,可是把我當時計劃寫這個組件的基本目的已經完成了。先給你們看看我最後寫出來的文件狀況:前端

image

也許有人會好奇,一個列表的功能怎麼會寫出這麼多東西出來?關於這個問題的答案,我稍後再來總結,先讓我描述下我寫這些東西以前產生的想法。jquery

1. 背景介紹

我是去年5月份在上家公司開始作的前端開發,在那個公司,我花了2周的時間,盡力寫了一套js的組件,用於咱們當時的一個管理系統的開發。你們都知道,在管理系統裏面,最多見的兩種頁面類型無非就是列表頁面和編輯頁面。拿列表頁面來講,它裏面用到的列表組件一般基於table進行開發的,當時考慮過jquery.datable這樣的插件,後來放棄了。緣由是:jquery.datatable有不少多餘的東西,我不須要;它的框架在使用時候的思路,跟我之前使用的其它公司開發平臺裏面列表組件徹底不一樣,我以爲我之前使用的組件思想更清晰簡單。因此我就憑本身當時的能力開發出了一個能知足如下一些功能的table組件:git

1. 分頁;2. 列寬拖拽;3. 序號列自動生成;4. 單選和多選;5. 列表頭固定,以便在列表區域滾動的時候,列表頭不會受滾動的影響;6. 樹形列表;7. 列表各類事件等。github

後來我不單是作管理系統了,還作了更面向普通用於的網站類應用和移動端應用。這個時候又根據產品的需求開發出了三個另外的列表組件:第一個是帶分頁工具欄的列表組件,這個組件至關於就是前面那個table組件的縮小版,只不過html結構上再也不使用table,並且也不須要拖拽,樹形控制那樣的功能了;第二個在第一個的基礎上去掉了分頁工具欄,改爲了利用window的滾動事件進行滾動翻頁,固然爲了留一個後路,這個組件提供了加載更多這樣的手工進行下一頁的按鈕;第三個使用於移動端,因爲移動端scroll事件必須得等到屏幕的滾動操做徹底中止下來之後纔會觸發,因此不能直接利用window的滾動事件,而改用了iscroll插件來模擬滾動,同時利用它提供的scroll事件來實現更加快速響應的滾動翻頁功能。數據庫

其實在我後來寫第二個組件的時候,我當時就在考慮:無論是後臺的列表也好,仍是前臺的列表也好,除了表現出來的樣子不同,它們在發送請求的方式,解析響應的方式,以及列表渲染的方式應該都是差很少的,並且在後臺的列表中,相似分頁排序這樣的功能,在前臺的列表裏面也有較爲常見的使用場景,既然如此,這些類似的東西,若是能抽象到一個父類裏面,而後由先後臺的列表組件去實現各自獨有的部分,這樣的代碼的結構會不會更加簡練一點。由於當時後臺的那個列表組件,我已經寫了1000多行了,本身有時候想改個東西,都要滾來滾去地閱讀之前寫的代碼,十分不便。編程

再拿後面的三個組件來講,滾動分頁與不滾動分頁組件的區別,僅僅在於分頁的控制不一樣而已,若是把分頁這一個部分徹底丟出去,那麼剩下的部分,就不須要在兩個組件裏面都去實現了,只用在一個類裏面實現一次。iscroll與window的scroll,也僅僅只是滾動事件的發佈者不一樣而已。若是我提供兩個不一樣的滾動翻頁的組件,一個使用window scroll實現,一個使用iscroll實現,而後由列表組件去決定要使用哪一個分頁組件,那麼代碼會更加簡潔。設計模式

假如按以上的思路實現,我以前寫的那些代碼,能夠獲得如下這些方面的改進:數組

1. 經過繼承解決掉代碼重複問題,並且加強了代碼的可維護性;瀏覽器

2. 經過職責分離,好比把分頁功能,排序功能從組件中分離出來,而後組件內部採用注入的方式進行使用,這樣一個列表想要更換分頁、排序等擴展功能就會變得很容易。

因此這也就是我寫前面截圖那些文件的由來。至於爲啥會有這麼多個,這都是因爲抽象出了一些公共的基類以及把分頁,排序等功能從列表組件內分離出來以後的結果,並且這些文件實際上包含了前面提到4種列表的全部功能,因此總的文件數就比較大了。在實際使用中,要使用某一個類型的列表的時候,基本上只要使用simpleListView, tableView , scrollListView , iscrollListView便可。另外拆分紅這麼多文件以後,每一個文件就變得很小了,基本上都是200行左右,沒有一個超過400行的,更容易閱讀理解。

因爲這一次的內容比較多,這篇文章沒法詳細的介紹全部內容,只能先把文件之間的結構以及應用場景介紹一下,後面幾篇文章會針對一些我以爲有必要進行解釋說明的內容進行補充。歡迎感興趣的朋友繼續關注後面的文章,我會在近期陸續總結出來,好在最近的工做應該不會像以前那麼忙。源代碼已經上傳到github,可經過下面幾個地址來獲取組件源碼以及demo的源碼:

組件源碼:

https://github.com/liuyunzhuge/blog/tree/master/form/src/js/mod/listView

demo源碼:

https://github.com/liuyunzhuge/blog/blob/master/form/src/js/app/listView_1.js

https://github.com/liuyunzhuge/blog/blob/master/form/src/js/app/listView_2.js

https://github.com/liuyunzhuge/blog/blob/master/form/src/js/app/listView_3.js

https://github.com/liuyunzhuge/blog/blob/master/form/src/js/app/listView_4.js

https://github.com/liuyunzhuge/blog/blob/master/form/src/js/app/tableView.js

接下來介紹下各個文件的具體做用。

2. 文件結構

1. base/listViewBase

它是全部列表組件的基類,基本上全部公共的事情,都是在它裏面處理的,好比排序組件初始化,分頁組件初始化,模板引擎管理組件初始化,以及請求發送和請求解析等。每個具體的列表管理組件都須要繼承它。在這個類裏面使用了模板方法的設計模式,以及在請求數據的先後,添加了多個事件回調,目的是爲了子類可以進行靈活的個性化擴展。

2. base/pageViewBase以及simplePageView

pageViewBase是全部分頁組件的基類。分頁組件無論內部如何實現,其實對外須要提供的接口或者事件都是相同的。對於列表組件來講,只須要知道分頁組件何時分頁參數發生改變了而已,而後在改變的時候,帶上最新的分頁參數從新請求數據。這個類從簡單封裝分頁功能pageView.js這篇文章中提到的pageView.js裏面抽象出來。那篇文章介紹的pageView.js的功能,如今只須要定義一個繼承pageViewBase的類,而後把pageViewBase未實現的那些具體邏輯添加進去便可,也就是如今的更加簡潔的simplePageView。

3. base/sortViewBase和sortFields

sortViewBase是全部排序組件的基類。排序組件的實現思路,其實跟分頁組件的思路很像,對於列表組件來講,只須要知道排序組件何時排序狀態發生了變化便可。就像不少的table插件同樣,通常列表都是單擊某列的標題便可使得列表的數據按該列進行不一樣方式的排序,排序組件負責實現的就是這些排序方式切換的操做邏輯。因爲排序組件,最終要給列表組件提供排序參數,因此又把排序參數的管理分離出來,寫成了sortFields類。這樣作的目的主要是爲了簡化sortViewBase的實現。在編程中,把數據的邏輯與UI的邏輯分開,每每是寫出更好代碼的關鍵。

4. base/tplBase和mustacheTpl

base/tplBase是模板引擎管理組件的基類。模板引擎管理組件用於渲染列表的數據。它聲明瞭兩個接口,compile和render,用來進行模板的編譯和模板的渲染。之因此要這麼寫,而是由於假若有人想採用這一套代碼的話,也許我這裏面用到的模板引擎並非他們團隊人員所熟練使用的,因此爲了可以更加靈活的適用其它模板引擎,我就把模板引擎的使用給抽象了。同時因爲我在代碼中都是使用mustache做爲模板引擎,因此我也提供了繼承tplBase的mustache版本的實現mustacheTpl。

5. simpleListView 和simpleSortView

看名字也能知道它們的做用了。simpleListView 繼承自listViewBase,simpleSortView繼承自sortViewBase。simpleListView 實現最簡單的分頁列表管理組件。simpleSortView給這個列表管理組件提供排序管理的功能。

6. scrollListView和scrollPageView

scrollListView繼承自listViewBase,scrollPageView繼承自pageViewBase。scrollListView實現相對於瀏覽器窗口或者某一個DOM元素進行滾動翻頁的列表組件,這個列表組件與simpleListView的區別不只僅是翻頁的不一樣,同時在數據的渲染和UI交互上也有區別,畢竟翻到下一頁的時候,須要一些更加友好的加載提示,以及不能刪除以前已加載的數據內容。scrollPageView用來實現加載更多的翻頁功能。

7. iscrollListView和iscrollPageView

跟前面不同的是iscrollListView繼承自scrollListView,畢竟它跟scrollListView是有不少共性的,不過它比scrollListView多了一個iscroll實例的管理功能,由於它要用iscroll插件。iscrollPageView提供給iscrollListView針對iscroll插件的加載更多的翻頁功能。

8. tableView

它繼承自scrollListView。用來實現基於table的列表組件。支持單多選,支持獲取選中行的數據,支持按索引獲取行的數據,支持表頭固定等。它是全部列表組件中相對複雜的一個。但實際上只是功能多,邏輯並不複雜。

9. tableDrag和tableOrder

我把它們做爲插件提供給tableView,分別爲它提供列寬拖動以及序號列生成的功能。這麼作的目的也是考慮到儘量地簡化tableView的功能。畢竟列寬拖拽這些功能都屬於可選性質的。假如後面我想給tableView增長一個樹形列表的管理功能,那麼只要按照這兩個插件的實現方式再寫一個相似tableTree的插件便可。

10. tableDefault

這個純粹是爲了簡化實例化tableView時,提供一些默認的配置,好比插件的配置等等。

以上就是這些文件的基本做用。下面會結合demo來演示四個列表組件的實際使用方式。

3. simpleListView

demo地址:http://liuyunzhuge.github.io/blog/form/dist/html/listView_1.html

demo文件:https://github.com/liuyunzhuge/blog/blob/master/form/src/js/app/listView_1.js

實際效果:

image

頂部打印了列表組件在請求數據時傳遞給後臺的參數。排序組件因爲涉及到可能有多個排序字段,因此用數組字符串進行傳遞,各個字段在數組中的順序,表明它們在數據庫中進行排序時的前後關係。

相關使用代碼以下:

4. scrollListView

demo地址:

http://liuyunzhuge.github.io/blog/form/dist/html/listView_2.html

http://liuyunzhuge.github.io/blog/form/dist/html/listView_3.html#

demo文件:

https://github.com/liuyunzhuge/blog/blob/master/form/src/js/app/listView_2.js

https://github.com/liuyunzhuge/blog/blob/master/form/src/js/app/listView_3.js

這個之因此有兩個demo,那是由於第一個demo是相對於window進行滾動翻頁的,第二個demo是相對於某個DOM元素進行滾動翻頁的。

實際效果這裏就不展開了。畢竟這個demo要鼠標滾動操做才能看到更真實的效果。可經過前面的連接進行查看。

實際使用的代碼也不展現了,由於跟前面的simpleListView差很少。

5. iscrollListView

demo地址:

http://liuyunzhuge.github.io/blog/form/dist/html/listView_4.html

demo文件:

https://github.com/liuyunzhuge/blog/blob/master/form/src/js/app/listView_4.js

預覽的話能夠按F12切換的手機模擬器進行demo預覽,iscroll畢竟是移動端用的東西,pc端也能遇到,要用鼠標拖動才能進行滾動,我沒有啓用滾輪操做。其它的跟前面差很少。

6. tableView

demo地址:

http://liuyunzhuge.github.io/blog/form/dist/html/tableView.html

demo文件:

https://github.com/liuyunzhuge/blog/blob/master/form/src/js/app/tableView.js

實際效果:

image

tableView組件跟其它列表組件很大不一樣的一點是,它對html結構要求更加嚴格:

image

好在這個結構實際上是很是清晰的。之所要弄成這個,跟表頭固定的需求有關係,而後表頭滾定又會帶來其它相關的問題,這些我會在後面的文章再細說。

使用的方式是:

在demo代碼中還能夠看到,tableView組件使用colgroup和tableHd兩個option來定義列寬描述以及表頭內容的html模板,之因此不直接寫在html裏面,也是爲了html的簡潔考慮。若是放在js裏面的話,反而更統一一些,畢竟表體部分的html模板就是js中進行定義的。

經過以上這些demo能夠看到,雖然前面定義了不少文件,可是在使用的時候,這些組件用起來並不複雜,要是結合我以前寫的那些跟form相關的組件,那麼去作一些帶查詢列表的列表管理功能也不是很難,基本只須要list.query(appForm.getData())便可。歡迎感興趣的朋友前去使用,這些都是我已經在實際項目中使用了之後感受比較省時省力的方法,不比一些有名的jquery插件差。

7. 本文小結

總之,我是想到全部的列表的功能都具有類似性,不想在一個項目中,組件層面存在重複的代碼,因此就寫了這些東西,力求從此我在新項目中,可以將代碼的重複度降到最低,方便維護跟擴展。本文也只是把我這段時間的成果起了個頭,大致上介紹了下我寫的這些列表組件的做用以及用法,可是裏面還有不少的細節尚未徹底說明,爲了讓人看得更加明白,我這幾天會加速把相關內容總結出來。最後,但願這些東西無論是學習仍是工做方面,都能給一些朋友帶來實際的幫助。若是以爲裏面有什麼很差的、不對的,歡迎幫我指出。

相關文章
相關標籤/搜索