欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS控件的生命周期介紹

 更新時(shí)間:2012年10月22日 22:50:32   作者:  
JS控件的生命周期跟其他平臺(tái)UI的生命周期類(lèi)似,但是又有自己的特點(diǎn),我們只有將控件的生命周期劃分清晰,所有的控件編寫(xiě)、mixins的編寫(xiě)和plugin的編寫(xiě)才能遵循控件的生命周期做統(tǒng)一的管理

JS控件的生命周期跟其他平臺(tái)UI的生命周期類(lèi)似,但是又有自己的特點(diǎn),我們只有將控件的生命周期劃分清晰,所有的控件編寫(xiě)、mixins的編寫(xiě)和plugin的編寫(xiě)才能遵循控件的生命周期做統(tǒng)一的管理。在這里我把JS的生命周期定義為4部分:

1.initializer: 初始化,做一些不牽扯DOM操作的初始化操作
2.createDom: 創(chuàng)建 DOM,在這個(gè)過(guò)程中我們創(chuàng)建控件需要的DOM結(jié)構(gòu)
3.renderUI: 生成控件的內(nèi)部元素,在這里調(diào)用子控件的渲染方法,開(kāi)啟子控件的生命周期
4.bindUI: 綁定事件,可以綁定子控件事件也可以綁定內(nèi)部DOM的事件
5.synUI: DOM結(jié)構(gòu)以及子控件生成完畢后,我們?cè)谂渲庙?xiàng)中傳入的值或者默認(rèn)的配置項(xiàng)要應(yīng)用到DOM上,例如 width,height,focusable之類(lèi)的屬性
6.destructor: 析構(gòu)函數(shù),移除控件,清理控件上的事件,清理子控件,清理控件自己的DOM以及控件的一些對(duì)其他控件的引用。


1

初始化:

控件初始化過(guò)程中做以下事情:
1.調(diào)用繼承的父類(lèi)的初始化函數(shù),包括原型鏈上的父類(lèi)和mixins
2.處理配置項(xiàng),合并默認(rèn)配置項(xiàng)和用戶(hù)傳入的配置項(xiàng)
3.處理綁定到改對(duì)象的事件
4.初始化插件(plugin)
初始化完成后,是否創(chuàng)建DOM看具體的策略,類(lèi)似于ext的實(shí)現(xiàn),可以延遲創(chuàng)建DOM

創(chuàng)建DOM

創(chuàng)建DOM的過(guò)程如下:
1.調(diào)用繼承的父類(lèi)的創(chuàng)建DOM的函數(shù),包括原型鏈上的父類(lèi)和mixins
2.創(chuàng)建控件的DOM
3.調(diào)用控件插件的創(chuàng)建DOM的函數(shù)

渲染子控件和內(nèi)部DOM操作

執(zhí)行過(guò)程如下:
1.調(diào)用父類(lèi)的渲染函數(shù),包括原型鏈上的父類(lèi)和mixins
2.調(diào)用插件的渲染函數(shù)
我們可以在頂級(jí)的父類(lèi)來(lái)初始化子控件。好處是,子類(lèi)不需要做子控件初始化的操作此時(shí):
1.如果子控件還未初始化則執(zhí)行初始化
2.繼續(xù)執(zhí)行子控件的創(chuàng)建DOM、渲染子控件、綁定事件、同步配置項(xiàng)函數(shù)執(zhí)行
綁定事件
由于此時(shí)控件的DOM和內(nèi)部的子控件已經(jīng)渲染完畢,則可以在子控件或者DOM上綁定事件。綁定事件的過(guò)程:
1.調(diào)用父類(lèi)的綁定事件方法,包括原型鏈上的父類(lèi)和mixins
2.調(diào)用插件(plugin)的綁定事件方式
注意:在子控件或者內(nèi)部DOM上綁定事件時(shí),使用委托,不要直接在子控件或者DOM上綁定事件,一旦子控件添加或者刪除,內(nèi)部DOM變化都會(huì)引起事件失效。

同步配置項(xiàng)

首先說(shuō)明一下什么叫做同步配置項(xiàng),前面我們?cè)诔跏蓟丶r(shí),已經(jīng)對(duì)配置項(xiàng)做過(guò)一定的處理(至于如何處理,后面講 JS控件屬性 的時(shí)候會(huì)講到),但是配置項(xiàng)并未作用到DOM上或者內(nèi)部子控件上。
為什么在這時(shí)候處理同步,而不是在創(chuàng)建DOM和渲染子控件時(shí),有2個(gè)原因:
1.在創(chuàng)建DOM和渲染子控件時(shí),所有的DOM和子控件并未完整生成此時(shí)同步需要進(jìn)行大量判斷
2.我們需要把同步配置項(xiàng)的工作提取成方法,修改配置項(xiàng)時(shí),內(nèi)部DOM和子控件跟著變化。

例如:配置項(xiàng)里有 { width : 100 }
1.如果我們?cè)阡秩綝OM時(shí)同步,則可能把“width=100px;”直接設(shè)置到DOM上,而到我們需要修改這個(gè)width時(shí),我們還需要寫(xiě)一個(gè)函數(shù)來(lái)設(shè)置這個(gè)值。
2.反之,我們把同步配置項(xiàng)集中處理,將一個(gè)個(gè)的同步配置項(xiàng)的過(guò)程抽取成一個(gè)個(gè)函數(shù),那么我們初始化 width的過(guò)程和修改width的過(guò)程完全一樣,這樣概念和邏輯就統(tǒng)一起來(lái)。
同步配置項(xiàng)的過(guò)程依然如其他步驟一樣:
1.調(diào)用父類(lèi)的同步方法,包括原型鏈上的父類(lèi)和mixins
2.調(diào)用插件(plugin)的同步方法
注意:我們應(yīng)該可以配置一個(gè)配置項(xiàng)是否在此時(shí)同步,原因有很多,比如多個(gè)配置項(xiàng)會(huì)產(chǎn)生同一操作,如果多個(gè)配置項(xiàng)同時(shí)同步,那么一個(gè)過(guò)程會(huì)反復(fù)執(zhí)行多次。
移除控件
任何對(duì)象都有構(gòu)造函數(shù),必定也有析構(gòu)函數(shù),但是這個(gè)函數(shù)往往是大家最容易忽視的地方,但是也是非常重要的地方,暫且不說(shuō)內(nèi)存泄露之類(lèi)的問(wèn)題,就是如果一個(gè)控件的移除工作做得不夠好,會(huì)對(duì)正常的使用帶來(lái)很大的麻煩。
這個(gè)函數(shù)又是最不好寫(xiě)的一個(gè)函數(shù),因?yàn)樗枰幚硪韵鹿ぷ鳎?
1.清理使用的其他控件,是否也移除看具體情形。區(qū)分 關(guān)聯(lián)和聚合
2.清理子控件
3.清理綁定到控件和DOM上的事件
4.移除DOM
5.清理變量的引用,這個(gè)比較麻煩和繁瑣,所以我們需要對(duì)控件的引用做統(tǒng)一的管理
同樣此函數(shù)也要執(zhí)行:
1.調(diào)用父類(lèi)的析構(gòu)函數(shù),包括原型鏈上的父類(lèi)和mixins
2.調(diào)用插件的析構(gòu)函數(shù)

問(wèn)題

上面講的全部是具體的步驟,但是在實(shí)現(xiàn)的時(shí)候遇到了一系列的問(wèn)題:
1.調(diào)用父類(lèi)的方法存在問(wèn)題
1)調(diào)用原型鏈上的父類(lèi)方法,只能使用 className.superclass.method.call(this)這類(lèi)的方法,this.constructor.superclass.method.call(this)不能使用,原因在 js 控件繼承 的extend一章中有講到,這種調(diào)用方式繁瑣而且維護(hù)不方便。
2)調(diào)用mixins上的方法,在JS 繼承 mixins一章中我講到過(guò)mixins的實(shí)現(xiàn)原理,覆蓋同名方法,mixins的方法其實(shí)已經(jīng)作為控件的prototype上的方法,所以最好不要使用同名方法,如果多個(gè)mixins都是用 renderUI,synUI之類(lèi)的方法,而繼承這些mixins的控件沒(méi)有實(shí)現(xiàn)renderUI這類(lèi)方法,那么就會(huì)被覆蓋。
2.調(diào)用插件的方法也存在問(wèn)題
1)我們需要獲得當(dāng)前控件的引用

解決方式:

1. 針對(duì)調(diào)用父類(lèi)的方法我們可以在控件渲染時(shí),按照原型鏈的順序,先調(diào)用父類(lèi)的方法再調(diào)用子類(lèi)的方法直到當(dāng)前控件:


如上面的繼承關(guān)系,我們執(zhí)行C.renderUI()時(shí),按照繼承原型鏈的頂層向下執(zhí)行。
2. 執(zhí)行minxins的方法,我們執(zhí)行renderUI時(shí),去依次執(zhí)行 mixin 的__renderUI方法。
3. 執(zhí)行父類(lèi)的renderUI 時(shí),如果也存在mixins那么執(zhí)行mixin的 __renderUI方法。



圖3

如上圖所示: inherits表示原型鏈繼承,extends表示 mixin擴(kuò)展
那么c.renderUI的執(zhí)行過(guò)程如下:

A.renderUI ->D.__renderUI->B.renderUI->E.__renderUI->C.renderUI
3. 調(diào)用插件方法時(shí)需要傳遞控件本身的引用即可,如:
plugin1.render(this)
4. 析構(gòu)函數(shù) destructor比較特使,執(zhí)行的順序跟上面2中講的順序有所不同:
子類(lèi) destructor -> 子類(lèi)擴(kuò)展 destructor -> 父類(lèi) destructor -> 父類(lèi)擴(kuò)展 destructor
按照?qǐng)D3的繼承結(jié)構(gòu)其析構(gòu)函數(shù)執(zhí)行的順序是:
C. destructor ->E.__destructor->B.destructor->E.__destructor->a.destructor
原因是,子類(lèi)的一些引用依賴(lài)于父類(lèi)或者擴(kuò)展類(lèi),如果父類(lèi)和擴(kuò)展類(lèi)先執(zhí)行析構(gòu)函數(shù),那么子類(lèi)在使用某些變量/屬性時(shí)會(huì)報(bào)錯(cuò)。

這一節(jié)我把控件的生命周期講了一遍,所有的著一些都是來(lái)自于 KISSY框架的UIBase,感興趣的可以去看一下,非常精彩的實(shí)現(xiàn)http://docs.kissyui.com/kissy/docs/#!/api/KISSY.Component.UIBase

相關(guān)文章

最新評(píng)論