亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Backbone源碼解讀(三)

feng409 / 1091人閱讀

摘要:事件關(guān)于路由觸發(fā)事件是通過兩個函數(shù)來完成的,它們分別是和前者會檢測路由是否發(fā)生了改變,如果改變了就會觸發(fā)函數(shù)并調(diào)用函數(shù),而后者會通過路由片段來找到相關(guān)的事件函數(shù)來觸發(fā)。

注意:強(qiáng)烈建議一邊閱讀源碼一邊閱讀本文。

終于到了backbone源碼解讀的最后一篇,這一篇和前面幾篇時間上有一定的間隔(因?yàn)橐貙W(xué)校有一堆亂七八糟的事...)。在這一篇里面會講解Bakcbonesync & router & histrorysync比較簡單,但是路由的部分就比較復(fù)雜了。個人覺得是整個backbone源碼里面最不好懂的一個部分,這個部分也使得backbone可以方便實(shí)現(xiàn)可以“返回”的單頁面應(yīng)用。個人覺得這個部分其實(shí)并沒有很MVC有很密切的關(guān)系,但是它非常重要。讀過源碼就會發(fā)現(xiàn),其實(shí)這一個部分與其他的模塊(Model,Collection & View)相對獨(dú)立。如果不希望使用backbone但希望能用到這個路由系統(tǒng)的話估計拆出來難度也不會很大。

總體來說路由模塊由RouterHistrory組成,而Router事實(shí)上可以看成是對History的一個封裝。用戶直接操作的部分時Router,相關(guān)函數(shù)的處理(路由匹配時調(diào)用的函數(shù))也是在Router中完成。History主要是處理一個更加棘手的問題,就是有關(guān)鏈接的問題。這里面有關(guān)于跨瀏覽器的解決方案是非常值得學(xué)習(xí)的。

1. Router

Router是對History的封裝,也是給用戶定義路由的接口。一般來說,用戶在使用Router的時候會定義一個routers的對象,里面是想關(guān)路由與處理函數(shù)組成的key-value。Router代碼中主要做兩件事,一件是對正則表達(dá)式的操作(可以看見里面很多令人痛苦的正則表達(dá)式),另一件事就是事件相關(guān)的綁定了。Router的相關(guān)代碼不多,寫得比較精簡。

1.1 函數(shù)綁定與執(zhí)行

Router里面定義了兩種方法來定義路由事件,一個方法是用戶定義routers,通過初始化調(diào)用_bindRoutes函數(shù);一個方法是用自帶的route函數(shù)。其實(shí)兩個方法本質(zhì)上都是調(diào)用了route函數(shù)_bindRoutes里面實(shí)際上也是通過循環(huán)來調(diào)用route函數(shù)。因此路由函數(shù)重點(diǎn)在于route函數(shù)。

route函數(shù)里面,一開始是進(jìn)行一些參數(shù)的整理。然后就是調(diào)用了History模塊的route函數(shù),把正則(匹配參數(shù)用的)和一個回調(diào)函數(shù)傳了進(jìn)去。在回調(diào)函數(shù)里面就是做 執(zhí)行函數(shù)——觸發(fā)router的事件——觸發(fā)history的事件這幾個步驟,在Historyroute函數(shù)里面,只是簡單的插入地把keycallback組成對象插入handlers數(shù)組里面而已。

1.2. 正則表達(dá)式轉(zhuǎn)化與使用

Router函數(shù)里面最難懂也非常重要的部分是格式的轉(zhuǎn)換。在Router里面有兩個重要的函數(shù)_routeToRegExp函數(shù)和_extractParameters兩個,這兩個函數(shù)與正則密切相關(guān)。

_extractParameters函數(shù)的作用是利用正則表達(dá)式,把傳進(jìn)來的url片段fragment分割成片段存進(jìn)數(shù)組當(dāng)中。這些片段是真實(shí)的已經(jīng)匹配出來的參數(shù),在route函數(shù)里面會把這些參數(shù)傳給用戶定義的函數(shù)里面,供用戶使用。

_routeToRegExp函數(shù)是一個簡單,但要完全理解很難的函數(shù)。這個函數(shù)的作用就是返回一個RegExp對象,通過這一個對象來匹配當(dāng)前的鏈接,然后從中得到參數(shù)。進(jìn)入這個函數(shù)之后會通過字符串的replace函數(shù),匹配出路由的是哪幾(或一)種情況,并且替代成可以捕獲參數(shù)的正則字符串。比如說把路由定義里的/:page或者*fragment這樣的字符串通過事先定義好的幾個正則匹配到,然后換成帶()的可以捕獲的形式,然后在創(chuàng)建正則去捕獲真正需要的常數(shù)。

2. History

backbone中對于History模塊的使用是通過用構(gòu)造方式調(diào)用(new)返回一個可以使用prototype方法的對象來實(shí)現(xiàn)的。Backbone.history = new History; 這個模塊非常重要,而且在整個backbone里面可以說是最難完全讀懂的。下面我會從三個方面來講:一個方面是有關(guān)于路徑格式處理的問題,在這方面也有很多和正則表達(dá)式相關(guān)的函數(shù);另一個方面是最關(guān)鍵的一個方面,就是History檢測瀏覽器來使用不同的路由控制方式;最后一個方面就是通過具體的函數(shù)來講解它是如何實(shí)現(xiàn)第二點(diǎn)各方面所說的控制的。

History從接口的角度來說有start函數(shù)作為初始化的設(shè)置,還有通過Router模塊封裝的navigate方法。Router里面的很多處理需要調(diào)用到這個模塊的方法。

History事實(shí)上也是對location/history一定程度上的封裝。很多時候是通過location模塊來讀取匹配,通過history的一些方法來進(jìn)行路由控制。

2.1 路徑格式處理
2.1.1 root

用戶可以設(shè)置root,作為根路徑。這個根路徑在模塊中有一些判斷和處理的地方。比方說確定當(dāng)前是否在根路徑,或者在當(dāng)前URL提取出相應(yīng)的錨點(diǎn)等等都需要用到root這個內(nèi)部變量。

2.1.2 getFragment

在這個函數(shù)里面我們可以看到URL的格式分為了兩種。一種是hash方式,一種是search方式(主要是兼容較老的瀏覽器)。在這里通過判斷來進(jìn)行瀏覽器能力檢測。對于大部分現(xiàn)代瀏覽器來說,事實(shí)上大都是使用hash方式獲取錨點(diǎn)#后面的URL片段。

2.2 路由控制的三種方法(核心)
2.2.1 onhashchange方式

這種方式是通過監(jiān)聽"hashchange"事件,然后觸發(fā)事件,用location.hash.replace方法來改變路由。

2.2.2 pushstate方式

這種方式是最為推薦的HTML5方式。使用historypushState方法修改history里的記錄,然后也可以通過監(jiān)聽popstate來觸發(fā)一些相關(guān)的事件。

2.2.3 iframe方式

這是一個非常巧妙但是從某種程度上非?!俺舐钡姆椒?。丑陋是在它比較吃性能,一方面它有很多dom的操作來設(shè)置iframe,最重要的方面是它還用了定時器每隔一小段時間就檢測,然后就觸發(fā)函數(shù),判斷是否改變等等。插入一個空的iframe(經(jīng)過屬性設(shè)置)的作用在這里是存儲hash的值和存儲hash改變記錄。在這里我遇到了一個問題:存儲hash的值完全可以通過一個全局變量來完成,為什么要大費(fèi)周折創(chuàng)建一個iframe呢?下面是個人的一些猜測:

Opening and closing the iframe tricks IE7 and earlier to push a history entry on hash-tag change.

這是源碼中的一句注釋。用iframe的理由可能是為了通過開關(guān)iframe來存儲記錄。說實(shí)話具體是什么原理還不清楚,如果有人了解的話歡迎指教~

// 開關(guān)`iframe`
iWindow.document.open();
iWindow.document.close();
2.3 實(shí)現(xiàn)(start, navigate & 事件)
2.3.1 start

start主要做如下操作:

進(jìn)入start函數(shù)之后會把started設(shè)置為true防止重復(fù)出發(fā)。

設(shè)置各種參數(shù),用于后期判斷使用哪一種路由控制方式。

如果有hashchange事件,但沒有pushState方法,就用location.replace方法來改變路由。如果兩者都有就調(diào)用navigate函數(shù),里面可以通過pushState改變并記錄路由。如果兩者都沒有就設(shè)置iframe并啟動,通過設(shè)置iframehash參數(shù)來改變路由。

綁定事件,用hashChange方法的綁定hashchange事件,用pushState方法的綁定popstate事件,用iframe的使用setInterval來監(jiān)聽。

2.3.2 navigate

進(jìn)入函數(shù)之后首先是進(jìn)行“組合”,“組合”出url。這個過程需要有rootfragment,后者需要調(diào)用getFragment函數(shù),前者需要根據(jù)是path還是hash來對root進(jìn)行處理。如果是hash就不需要加/,如果是path就要加/。解碼后判斷當(dāng)前的this.fragment和有沒有發(fā)生變化,沒有不管,有就更新。

根據(jù)瀏覽器使用不同的方法。注意這里使用的判斷的依據(jù)是在start函數(shù)里面就定義好的。

如果有pushState或者replaceState就用;

如果有hashchange就僅僅只調(diào)用_upadateHash,傳入當(dāng)前的location bom對象,里面用了location.replace,更新當(dāng)前的href或者hash;

如果沒有hashchange就需要把當(dāng)前locationiframe.location對象分別傳入_updateHash,然后更新當(dāng)前href或者hash。

還有一個需要注意的是是否replace,這是一個傳入?yún)?shù),判斷時候要影響history。

2.3.3 事件

關(guān)于路由觸發(fā)事件是通過兩個函數(shù)來完成的,它們分別是checkUrlloadUrl, 前者會檢測路由是否發(fā)生了改變,如果改變了就會觸發(fā)navigate函數(shù)并調(diào)用loadUrl函數(shù),而后者會通過路由片段來找到handlers相關(guān)的事件函數(shù)來觸發(fā)。這就實(shí)現(xiàn)了用戶在routes對象里面設(shè)置的事件了。

3. Sync

最后來個簡單的Sync的講解吧~有關(guān)ajax的部分在backbone中其實(shí)是通過Backbone.ajax函數(shù)來代理jquery或者其他可以發(fā)起ajax的庫的。而Sync函數(shù)事實(shí)上主要的工作就是部署ajax參數(shù),最后調(diào)用這個Backbone.ajax發(fā)起請求。通過源碼可以看到,其中為params設(shè)置了type, dataType, url, contentType, data, (processData)屬性來作為發(fā)起ajax的參數(shù)。其中也為options設(shè)置了beforeSend, error方法作為ajax的回調(diào)(success函數(shù)寫在其他模塊中,詳情可以看我之前的幾篇文章)。

其中還需要主要的有兩個參數(shù)emulateJSON & emulateHTTP。在文檔中的介紹非常詳細(xì),個人覺得在大部分時候都不會用到。

4. 最后的話

終于把最后的第三篇文章寫出來了...花了很長時間...還是覺得如果要真正完全讀懂backbone源碼要多讀代碼(慚愧,自認(rèn)為還沒完全達(dá)到),多查資料,多讀一些源碼解析。有關(guān)于routerhistory我覺得這篇文章還是很棒的。這一個部分個人感覺確實(shí)不是很好懂,但是可以學(xué)習(xí)到很多有關(guān)路由的處理的相關(guān)知識,其實(shí)是非常有益的~

backbone被稱為框架的框架。這個框架的思想比起使用更有意義,畢竟現(xiàn)在有更多功能強(qiáng)大的框架。新東西要學(xué),但是經(jīng)典也是不應(yīng)該被落下的。

如果這篇文章有什么錯誤的地方請輕噴~互相學(xué)習(xí)!謝謝大家。

下面是全部的文章:
基于 Backbone + node 的個人簡歷生成器(個人學(xué)習(xí)總結(jié))
Backbone源碼解讀(一)
Backbone源碼解讀(二)
Backbone源碼解讀(三)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/80287.html

相關(guān)文章

  • Backbone 源碼解讀(一)

    1. 開場 1.1 MVC? MVC是一種GUI軟件的一種架構(gòu)模式。它的目的是將軟件的數(shù)據(jù)層(Model)和視圖(view)分開。Model連接數(shù)據(jù)庫,實(shí)現(xiàn)數(shù)據(jù)的交互。用戶不能直接和數(shù)據(jù)打交道,而是需要通過操作視圖,然后通過controller對事件作出響應(yīng),最后才得以改變數(shù)據(jù)。最后數(shù)據(jù)改變,通過觀察者模式更新view。(所以在這里需要用到設(shè)計模式中的觀察者模式) 1.2 Smalltalk-80...

    Kosmos 評論0 收藏0
  • Backbone源碼解讀(二)

    摘要:以為例構(gòu)造函數(shù)的內(nèi)容構(gòu)造函數(shù)的內(nèi)部一般會做以下幾個操作各種給內(nèi)部對象設(shè)置屬性。為什么呢源碼做出了解釋。在里面會調(diào)用用戶傳入的回調(diào)函數(shù)并觸發(fā)事件表示已經(jīng)同步了。整個的源碼事實(shí)上就是這兩組東西。 1. 開場 強(qiáng)烈建議一邊看著源碼一邊讀本文章,本文不貼大段代碼。源碼地址。在寫backbone應(yīng)用的時候,說實(shí)話,大部分的時間都是在寫這三個模塊的內(nèi)容。關(guān)于這三個模塊的分析網(wǎng)上隨隨便便就能找到一堆...

    Sleepy 評論0 收藏0
  • 帶你讀Backbone源碼解讀之Events實(shí)現(xiàn)

    摘要:接受個參數(shù),包括事件的名稱,回調(diào)函數(shù)和回調(diào)函數(shù)執(zhí)行的上下文環(huán)境。保留回調(diào)函數(shù)在數(shù)組中取出對應(yīng)的以及中的函數(shù)。當(dāng)然,你同樣可以在綁定的回調(diào)函數(shù)執(zhí)行前手動通過將其移除。 Backbone源碼解讀 Backbone在流行的前端框架中是最輕量級的一個,全部代碼實(shí)現(xiàn)一共只有1831行1。從前端的入門再到Titanium,我雖然幾次和Backbone打交道但是卻對它的結(jié)構(gòu)知之甚少,也促成了我想讀...

    AndroidTraveler 評論0 收藏0
  • backbone源碼解讀

    摘要:個人認(rèn)為,讀懂老牌框架的源代碼比會用流行框架的要有用的多。另外,源代碼中所有的以開頭的方法,可以認(rèn)為是私有方法,是沒有必要直接使用的,也不建議用戶覆蓋。 寫在前面 backbone是我兩年多前入門前端的時候接觸到的第一個框架,當(dāng)初被backbone的強(qiáng)大功能所吸引(當(dāng)然的確比裸寫js要好得多),雖然現(xiàn)在backbone并不算最主流的前端框架了,但是,它里面大量設(shè)計模式的靈活運(yùn)用,以及令...

    Kross 評論0 收藏0
  • backbone源碼解讀

    摘要:個人認(rèn)為,讀懂老牌框架的源代碼比會用流行框架的要有用的多。另外,源代碼中所有的以開頭的方法,可以認(rèn)為是私有方法,是沒有必要直接使用的,也不建議用戶覆蓋。 寫在前面 backbone是我兩年多前入門前端的時候接觸到的第一個框架,當(dāng)初被backbone的強(qiáng)大功能所吸引(當(dāng)然的確比裸寫js要好得多),雖然現(xiàn)在backbone并不算最主流的前端框架了,但是,它里面大量設(shè)計模式的靈活運(yùn)用,以及令...

    wangxinarhat 評論0 收藏0

發(fā)表評論

0條評論

feng409

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<