VM表單是一種高仿Vue的封裝,從Vue的角度來說容燕,比如我們登錄頁面的vue里面定義了一個params對象桥狡,用來收集登錄需要用到的參數(shù)。
<input placeholder="用戶名" ? v-model="params.name" />
<input placeholder="密碼" ? v-model="params.password" />
在vue的內(nèi)部颅围,只要用戶在輸入框中輸入了值就會實時的被vue放到params中伟葫。我們這里和vue如出一轍。
首先所有的表單類屬于我們需要特別要關(guān)注的對象院促,所以但他們是來自不同的類筏养,我們需要把這些來自不同的類統(tǒng)一管理(因為他們有很多共性),我們抽取一個VMProtocol協(xié)議常拓,用來標(biāo)識這是一個表單類:
表單類:要么收集數(shù)據(jù)(vid)渐溶,要么觸發(fā)事件(clickEvent)。
protocol?VMProtocol {
? ?var baseActivity: BaseActivity? ? ? ?//這個組件所屬的activity弄抬,
? ? var vid: String = "" ?//這個一般是輸入框用的
? ? var clickEvent: String = "" ?//這個一般是按鈕用的
}
嚴(yán)格來說上面的BaseActivity類型不準(zhǔn)確茎辐,因為安卓還有tab頁面不是activity,之前我們已經(jīng)用協(xié)議統(tǒng)一了,所以這個類型最好是BasePageInterface.?
現(xiàn)在可以開始布局了拖陆。輸入框按不同的頁面填充vid弛槐,按鈕就填寫clickEvent。當(dāng)頁面布局好之后依啰,頁面是不是在運行的時候觸發(fā)onLoad呢乎串。當(dāng)一會發(fā)生點擊事件的時候,按鈕需要調(diào)用到所屬頁面的js方法速警。但目前按鈕怎么知道當(dāng)前頁面在哪呢叹誉,這需要我們寫代碼來得到。
另外坏瞄,我們可以不用這么麻煩桂对,點擊按鈕的時候,手寫點擊事件鸠匀,再通過當(dāng)前頁面調(diào)用js蕉斜。這樣確實沒問題,不過當(dāng)頁面按鈕或輸入框多的時候你會發(fā)現(xiàn)這是一個重復(fù)內(nèi)枯燥的體力活缀棍,完全沒必要做這個重復(fù)的工作宅此。而且應(yīng)該簡潔封裝,達(dá)到布局完頁面功能就好的目的爬范。
再觀察下vue的語法父腕,輸入框僅僅是綁定了key,按鈕僅僅是寫了一個事件名青瀑,所有功能就對了璧亮,就應(yīng)該這么簡潔簡單。
我們在BaseActivity的onLoad里面斥难,此時所有的控件均已經(jīng)加載完成了枝嘶。我們從BaseActivity根視圖中?遞歸?查詢所有的VMProtocol。
特別注意:應(yīng)該是遞歸查詢哑诊,因為子視圖的嵌套可能有多層群扶。
細(xì)節(jié):
(1)當(dāng)一個view的子views數(shù)組的length=0,說明沒有子視圖镀裤,可以不用遞歸竞阐。
(2)當(dāng)一個view是按鈕,switch暑劝,列表等(這里是ios思維)復(fù)雜控件也可以不用遞歸骆莹,嚴(yán)格說應(yīng)該是可能有子view的才遞歸。
(3)當(dāng)這個view本身就是VMProtocol铃岔,其實也可以不用遞歸了汪疮。因為已經(jīng)找到了峭火。
從結(jié)果上,找到了VMProtocol之后智嚷,我們只需要做一件事:
vm.baseActivity = this
或者
vm.basePageInterface = this
比如按鈕:未來卖丸,當(dāng)這個按鈕發(fā)生點擊事件,這個button就可以拿到baseActivity盏道,繼而就可以調(diào)用js這個方法混編了稍浆。
一、封裝VMTextField猜嘱, 輸入框(多行文本域同理)
class?VMTextField: TextField衅枫, VMProtocol?{ //遵守VMProtocol協(xié)議
? ??????var basePageInterface: BasePageInterface? ? ? ?//這個組件所屬的activity,
? ? ? ? fun init(){ ? //控件初始化
? ? ? ? ? ? self.addEventLister("inputEvent",{ ? ?//自己就在內(nèi)部監(jiān)聽自己的實時輸入事件
? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? this.basePageInterface.js("vmodel", ?{vid: this.vid, value: this.value})
????????????????})
? ? ? ?}
}
這個回調(diào)特別注意下:
(1)控件拿到所在頁面basePageInterface
(2)拿到了頁面朗伶,就能調(diào)用js方法混編了弦撩,混編的時候需要指明這是表單的action=vmodel, vid為指定要求的vid值,value就是輸入框現(xiàn)在的值论皆。
? ?(3)vid一般是服務(wù)器字段益楼,比如登錄頁面的用戶名vid=name,密碼vid=pwd点晴。
二感凤、封裝VMButton:
這個很簡單了,和上面一樣粒督,只是監(jiān)聽點擊事件陪竿,并在點擊后調(diào)用
this.basePageInterface.js(this.clickEvent, ?{data: this.data})
其中clickEvent為點擊事件名,data為區(qū)分相同事件的參數(shù)(我的頁面有體現(xiàn))屠橄。
我們現(xiàn)在有了VMButton,VMTextField, VMTextview族跛,可以實現(xiàn)很多頁面的功能了。