摘要:組織大表單應(yīng)用中代碼的一種方法問題,動(dòng)機(jī),目的超過一屏,屬性復(fù)雜到一定程度的錄入界面系統(tǒng)中,缺乏良好架構(gòu)的代碼往往容易失控。改變樹結(jié)構(gòu)更換表單控件等改變展現(xiàn)方式的需求不應(yīng)當(dāng)對(duì)產(chǎn)生毀滅性打擊。
組織大表單應(yīng)用中javascript代碼的一種方法 問題,動(dòng)機(jī),目的
超過一屏,屬性復(fù)雜到一定程度的錄入界面/系統(tǒng)中,缺乏良好架構(gòu)的javascript代碼往往容易失控。尤其是當(dāng)規(guī)模從小型表單開始逐漸變大時(shí),javascript代碼很容易演變成已DOM為核心的、缺乏結(jié)構(gòu)、滿是hack且難以維護(hù)的狀態(tài)。
我認(rèn)為良好可維護(hù)的JS代碼應(yīng)該具有以下的特性
單個(gè)文件應(yīng)該控制在一千行以內(nèi)
依賴管理和合并,開發(fā)應(yīng)該單看一個(gè)JS文件就知道它依賴別的哪些代碼,而不是在HTML中直接列舉所有依賴,或者更糟,把所有超過2個(gè)頁面要用的JS全寫一起。
良好的代碼復(fù)用,清晰的模塊劃分
改變字段的表現(xiàn)形式或邏輯時(shí),不應(yīng)該需要修改/考慮/知道其他字段的邏輯和展現(xiàn)形式。改變DOM樹結(jié)構(gòu)、更換表單控件等改變展現(xiàn)方式的需求不應(yīng)當(dāng)對(duì)JS產(chǎn)生毀滅性打擊。
前三個(gè)問題基本可以歸結(jié)為,超過一千行的或是需要復(fù)用的JS代碼使用RequireJS / SeaJS 等方案進(jìn)行分解和管理。由于這是復(fù)雜JS工程的共性,這里不多做展開討論。本文主要關(guān)注最后一點(diǎn),也就是如何解除字段邏輯和展示之間的耦合,如何解除字段和其他字段的耦合。
解耦,協(xié)議,模板化解除耦合的做法不外乎將抽象出最小化的接口(協(xié)議)。字段可以有千奇百怪的各種邏輯,但抽象后發(fā)現(xiàn)其實(shí)針對(duì)單個(gè)字段來說,需要的最小接口非常小——簡直太適合解耦、正交化了
val 方法,傳值則寫入,不傳則讀?。╦Query風(fēng)格)
setReadonly 方法 設(shè)置只讀
setWritable 方法 設(shè)為可寫(當(dāng)然設(shè)計(jì)成setReadonly(false)也不壞)
change 事件 值被改變時(shí)觸發(fā)
error 事件 需要提示用戶這個(gè)字段有問題時(shí)觸發(fā)
訂好接口以后,每個(gè)字段只需要自己都實(shí)現(xiàn)接口,除了每個(gè)字段自己的實(shí)現(xiàn)代碼之外,外部一律通過接口來和字段交互。這樣代碼就整體可控可維護(hù),擴(kuò)展性和可讀性都能令人滿意。
有了這樣的接口,我們的邏輯實(shí)現(xiàn)就可以非常語義化,比如折扣鎖定為=現(xiàn)價(jià)/原價(jià)
good.discount.setReadonly(); var discountUpdate = function() { good.discount.val(good.price.val() / good.originalPrice.val()); }; good.price.addListener("change", discountUpdate); //注意:這不是DOM事件 good.originalPrice.addListener("change", discountUpdate);
這樣一段代碼完全不涉及dom交互,所以無論價(jià)格如何輸入展示,折扣如何展示都沒有問題。而實(shí)現(xiàn)dom交互的代碼也完全不必關(guān)心這個(gè)字段的邏輯如何,只需要實(shí)現(xiàn)前述接口,將輸入輸出、只讀、提示信息這些行為和DOM綁定即可。
最常用也是最多的綁定就是一個(gè)字段對(duì)應(yīng)一個(gè)DOM控件,這種綁定只需要簡單地將DOM事件轉(zhuǎn)發(fā)成自定義事件,將讀寫轉(zhuǎn)換成DOM控件讀寫即可;稍微復(fù)雜一些的交互涉及富文本編輯、日歷控件等輸入形式,由于我們的接口非常小,所以一般也無需太多的代碼。
問題往往來源于更復(fù)雜的一些字段,他們?cè)诔志没瘯r(shí)往往體現(xiàn)成JSON/XML格式字符串,或者是額外的擴(kuò)展表。這些字段往往無法輕易地用一個(gè)標(biāo)準(zhǔn)DOM控件來表現(xiàn),也往往是混亂的來源。
DOM操作難以維護(hù)的主要原因是插入、刪除元素的同時(shí)還要維護(hù)事件,在同一個(gè)頁面反復(fù)進(jìn)行各種操作的時(shí)候,邏輯容易有問題,所以我的做法是
事件用委托僅在初始化的時(shí)候綁在容器上一次
不多帶帶插入、刪除dom元素,而是以模板和數(shù)據(jù)渲染出所有元素
在內(nèi)存里維護(hù)一個(gè)變量存儲(chǔ)當(dāng)前的數(shù)據(jù),dom里面的數(shù)據(jù)并不具權(quán)威性
render渲染例程:
觸發(fā)點(diǎn):由change事件觸發(fā)
行為:從內(nèi)存讀取數(shù)據(jù)后(用模板)渲染出所有的DOM元素的HTML代碼,一次性吐在容器中
normalize規(guī)范化例程:
觸發(fā)點(diǎn):dom事件/val賦值 寫入數(shù)據(jù)時(shí)
行為:將輸入數(shù)據(jù)進(jìn)行規(guī)范化,然后寫入內(nèi)存并觸發(fā)change事件
校驗(yàn),提交由于復(fù)雜表單往往涉及同樣復(fù)雜的驗(yàn)證邏輯,建議盡可能將邏輯集中在后臺(tái)CGI,JS少做邏輯(否則同時(shí)維護(hù)兩套不同語言的等價(jià)的邏輯成本較大)
無論錯(cuò)誤是從CGI拿到,還是JS自己驗(yàn)出來,顯示錯(cuò)誤提示都一樣通過字段上的error事件來傳遞,校驗(yàn)代碼負(fù)責(zé)觸發(fā)事件,字段本身的實(shí)現(xiàn)代碼監(jiān)聽事件來在界面上顯示相應(yīng)的提示。
提交數(shù)據(jù)時(shí),只需要遍歷所有字段的集合,將他們的字段名和val()結(jié)果拼裝
DSL總而言之,解決混亂代碼的思路之一是將“需求/規(guī)則”和“表現(xiàn)/操作”分離,將前者抽象成某種形態(tài)的DSL,使之盡量貼近產(chǎn)品的需求,然后將后者作為這種DSL的解釋器來寫。代碼寫到像自然語言就贏了。如果做不到,不妨針對(duì)一個(gè)領(lǐng)域?qū)懡忉屍鱽斫忉尀槭裁催@些自然語言能工作。這是符合計(jì)算機(jī)科學(xué)發(fā)展大規(guī)律的,道法自然。
--EOF--
原文鏈接 http://mcfog.github.io/2013/06/dsl-style-javascript/
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/78076.html
摘要:因?yàn)橛脩舨挥迷诘谝淮芜M(jìn)入應(yīng)用時(shí)下載所有代碼,用戶能更快的看到頁面并與之交互。譯高階函數(shù)利用和來編寫更易維護(hù)的代碼高階函數(shù)可以幫助你增強(qiáng)你的,讓你的代碼更具有聲明性。知道什么時(shí)候和怎樣使用高階函數(shù)是至關(guān)重要的。 Vue 折騰記 - (10) 給axios做個(gè)挺靠譜的封裝(報(bào)錯(cuò),鑒權(quán),跳轉(zhuǎn),攔截,提示) 稍微改改都能直接拿來用~~~喲吼吼,喲吼吼..... 如何無痛降低 if else 面...
摘要:設(shè)計(jì)模式是一套可復(fù)用的,被眾人知曉,經(jīng)過編目分明的,經(jīng)驗(yàn)的總結(jié)。創(chuàng)建類安全工廠判斷是否調(diào)用關(guān)鍵字設(shè)計(jì)模式設(shè)計(jì)模式運(yùn)算符可以用來判斷某個(gè)構(gòu)造函數(shù)的屬性所指向的對(duì)象是否存在于另外一個(gè)要檢測對(duì)象的原型鏈上。 設(shè)計(jì)模式 是一套可復(fù)用的,被眾人知曉,經(jīng)過編目分明的,經(jīng)驗(yàn)的總結(jié)。作用:使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性 模式類型 創(chuàng)建型設(shè)計(jì)模式:解決對(duì)象在創(chuàng)建時(shí)產(chǎn)...
摘要:該區(qū)域代表可以被所控制的畫布。那么現(xiàn)在第二個(gè)問題,識(shí)別該文檔,這或許不是大部分用戶的需求,但小部分用戶并不意味著人數(shù)少。因此一個(gè)基于的請(qǐng)求于標(biāo)準(zhǔn)內(nèi)提出。 前言 作為程序員,技術(shù)的落實(shí)與鞏固是必要的,因此想到寫個(gè)系列,名為 why what or how 每篇文章試圖解釋清楚一個(gè)問題。 這次的 why what or how 主題:現(xiàn)在幾乎所有人都知道了 HTML5 ,那么 H5 到底相...
摘要:,微軟發(fā)布,同時(shí)發(fā)布了,該語言模仿同年發(fā)布的。,公司在瀏覽器對(duì)抗中沒落,將提交給國際標(biāo)準(zhǔn)化組織,希望能夠成為國際標(biāo)準(zhǔn),以此抵抗微軟。同時(shí)將標(biāo)準(zhǔn)的設(shè)想定名為和兩類。,尤雨溪發(fā)布項(xiàng)目。,正式發(fā)布,并且更名為。,發(fā)布,模塊系統(tǒng)得到廣泛的使用。 前言 作為程序員,技術(shù)的落實(shí)與鞏固是必要的,因此想到寫個(gè)系列,名為 why what or how 每篇文章試圖解釋清楚一個(gè)問題。 這次的 why w...
閱讀 787·2021-11-24 10:19
閱讀 1184·2021-09-13 10:23
閱讀 3506·2021-09-06 15:15
閱讀 1833·2019-08-30 14:09
閱讀 1763·2019-08-30 11:15
閱讀 1903·2019-08-29 18:44
閱讀 998·2019-08-29 16:34
閱讀 2517·2019-08-29 12:46