首頁  >  文章  >  web前端  >  AngularJS 實作按需非同步載入實例程式碼_AngularJS

AngularJS 實作按需非同步載入實例程式碼_AngularJS

WBOY
WBOY原創
2016-05-16 15:36:071053瀏覽

AngularJS 透過路由支援多視圖應用, 可以根據路由動態載入所需的視圖, 在 AngularJS 的文件中有詳細的介紹, 網路上也有不少教程, 就不用介紹了!

隨著視圖的不斷增加,js檔案會越來越多,而AngularJS 預設需要把全部的js都一次性加載,使用起來非常不便, 因此按需加載模組的需求會越來越強,不過,AngularJS 並沒有實作按需載入。

習慣了 seajs 的非同步加載方式,也想著 angular 也能同樣使用非同步加載,但是事實不隨人願。

angularjs 和requirejs 一樣,使用的是預先加載的方式組織模組(這和seajs 的懶加載正好相反),當一個單頁面應用的模組越來越多時,也就意味著需要預先加載的模組也會越來越多,這也許也說明了angular 比較適合用來開發輕應用。

正式開始

路由我使用了angular-ui-router,模組載入器是 requirejs

//路由
{
 state : 'login',
 templateUrl : 'login/login.html',
 controller : 'loginCtrl',
 resolve: {
  realCtrl : function ($q) {
   var def = $q.defer();
   require(['/features/login/login.js'], function (loginCtrl) {
    def.resolve(loginCtrl)
   });
   return def.promise;
  }
 }
},

// 获得$controllerProvider
app.config(function($controllerProvider) {
 app.registerController = $controllerProvider.register;
 // ...
})

// loginControler
app.registerController('loginCtrl', function ($scope) {
 // do something
});

angular應用實作隨選載入的方法

我們有個系統是用angular開發的,是一個單頁應用,隨著系統的迭代,首屏程式碼已經過於龐大,所以對系統進行改造。

我們主要面臨3個問題

1.是否需要模組載入框架?

2.非同步載入回來的頁面元件,如何註冊?

3.在什麼時機載入頁面元件?

針對第一個問題,由於angular本身已經有一套模組化方案,再引入模組載入框架有點冗餘,而且整體改造量比較大,所以不考慮。

因此只是實作了一個loadscript方法,用來載入元件。稍微要注意的是載入多個檔案時候的字串並行,和避免頁面重複切換時的重複載入。

第二個問題比較蛋疼,angular有「啟動」的說法,「啟動」發生在domcontentloaded之後,會把所有註入到主模組中的依賴編譯一遍。

啟動之後再想使用controller、deractive等api,會直接報錯


目前來看,解決這個問題,只有一個方法,就是利用主模組的provider主動註冊controller,但是由於provider不能直接使用,所以我們把它存在主模組下面。

透過存下來的方法,可以用來註冊非同步載入回來的頁面元件。缺點就是這樣子所有子頁面都掛在主模組下了。
針對第三個問題,由於營運平台是單頁應用,最好的載入時機應該是路由監聽到雜湊變化時,但是由於我們的路由是寫死的靜態配置,一開始沒找到什麼好的方法。
後來發現了這樣一個api

大概是說,在$routeChangeSuccess之前,我們還可以做些東西,把加載時機放在這裡最適合不過啦
具體實現大概是這樣子

至此,這個方案已經通了,剩下什麼工作?
1.整理程式碼,讓程式碼更通用化,我們以後開發新頁面,只需要在路由配置裡這樣寫就可以啦

2.把現有頁面都改造一下,由於之前沒有按需加載,不同頁面之間的service耦合嚴重,今後我們開發新頁面,就要注意不同頁面之間共用的service最好放在component下面

3.改構建,給路由裡的js引用換成cdn路徑。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn