當構建大型網站或應用程序在AngularJS許多/觀點的路線,它將不會加載所有的文件,如控制器、指令等是很好的,在第一次加載。理想情況下,在第一次加載,只有文物所需要的路線的問題,將加載。這可能是在一個下載或多取決于應用程序,但是,它只會是什么需要渲染特定的路由。當用戶導航App改變路線,其他文物尚未加載,將被加載時需要有。這種潛力不僅應該加快初始頁面的負載,而且還應該導致帶寬不被浪費。這個帖子,我的目的是展示的文物如控制器和指令可以實現與AngularJS的懶加載。 為了延遲加載的文物如AngularJS控制器和指示,有兩個主要問題,必須回答如下: 1、如何在應用啟動后,對一個模塊進行懶加載的注冊 2、在應用程序中,如何選擇腳本加載的實際位置
第一個問題的結果從當前無法注冊文物后,應用程序引導,使用模塊API。換句話說,如果你想與一個已經自舉程序登記一個新的控制器,使用下面的代碼:
angular.module('app').controller('SomeLazyController', function($scope){ $scope.key = '...';});you would get the following error when you reference the controller with the ng-controller directive:
Error: Argument ‘SomeLazyController’ is not a function, got undefined目前,唯一的方法(我知道)登記的文物已經引導應用程序,不使用模塊的API,但使用有關的AngularJS提供者代替。 供應商基本上是被用來創建和配置的AngularJS文物實例對象。因此,為了登記一個懶惰的控制器,你可以使用
現在與供應商的事情是,他們只有在模塊配置。因此,一個參考他們將不得不保持,以便他們可以用來以后登記懶惰文物。作為一個例子,為了獲得相關的供應商,您可以設置您的應用程序模塊類似以下:
appModule.js:(function(){ var app = angular.module('app', []); app.config(function($routeProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) { app.controllerProvider = $controllerProvider; app.compileProvider = $compileProvider; app.routeProvider = $routeProvider; app.filterProvider = $filterProvider; app.provide = $provide; // Register routes with the $routeProvider });})();You would then be able to define a lazy controller as follows:
angular.module('app').controllerProvider.resgister('SomeLazyController', function($scope){ $scope.key = '...';});仍然存在的問題,但是,在那里加載的懶惰文物,如上述控制器,將發生使用您的腳本加載器的選擇。目前,只有一個地方,這可以發生“干凈”,它是在“解決”屬性的路由定義。 當定義一個路由使用routeprovider美元,你可以指定一個可選的關鍵/工廠地圖的依賴,應注入路由控制器。使用“解決”屬性指定此依賴關系圖如下:
$routeProvider.when('/about', {templateUrl:'views/about.html', controller:'AboutViewController' resolve:{key:factory}依賴映射中的“鍵”將是依賴項的名稱,而“工廠”將是一個字符串,該字符串是作為依賴項的現有服務的別名,或作為其依賴項的返回值的可注入函數。現在,如果函數返回一個承諾,承諾將得到解決之前的路線是“渲染”(可以這么說)。因此,必須檢索異步的依賴,如延遲加載的文物,可以使用一個依賴圖的函數返回的承諾,將一次解決懶惰的文物已被加載的檢索。這確保了所有的懶惰文物加載之前的路線呈現。一個路由定義中指定要使用的懶惰依賴美元scr有一件事,也應該指出的是,由于承諾的決議將最有可能的AngularJS的上下文之外發生的,如在上面的例子中,它在scriptjs美元背景下發生的,AngularJS已經被明確告知當諾言已經解決(這么說)。這是通過承諾內的應用方法$rootscopeas在實現:
$rootScope.$apply(function(){ deferred.resolve();});如果承諾不解決在應用$rootscope,將不會對初始頁面加載渲染。 現在所有這些應用程序模塊定義,將產生以下:
appModule.js:(function(){ var app = angular.module('app', []); app.config(function($routeProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) { app.controllerProvider = $controllerProvider; app.compileProvider = $compileProvider; app.routeProvider = $routeProvider; app.filterProvider = $filterProvider; app.provide = $provide; // Register routes with the $routeProvider $routeProvider.when('/', {templateUrl:'views/home.html'}); $routeProvider.when('/about', {templateUrl:'views/about.html', resolve:{deps:function($q, $rootScope) { var deferred = $q.defer(); var dependencies = [ 'controllers/AboutViewController.js', 'directives/some-directive.js' ]; $script(dependencies, function() { // all dependencies have now been loaded by $script.js so resolve the promise $rootScope.$apply(function() { deferred.resolve(); }); }); return deferred.promise; }}}); });})();Finally you can bootstrap the app using code similar to the following if using $script.js:
$script(['appModule.js'], function(){ angular.bootstrap(document, ['app'])});這些都或多或少地要在AngularJS實現懶加載的步驟。總之,您將首先定義應用程序模塊以保持相關提供商的實例。然后,您將定義您的懶惰的文物登記自己使用的供應商,而不是模塊的API。然后使用一個“解析”函數返回你的路由定義中的一個承諾,你將加載所有的懶惰的文物和解決的承諾,一旦他們已經加載。這將確保所有的懶惰文物將提供相關的路線之前呈現。另外,別忘了解決承諾內rootscope美元。美元的申請,如果該決議將在AngularJS發生的事情。然后,您將創建一個“引導”的劇本,第一次加載的應用程序模塊,在引導程序。最后,你會鏈接到你的索引HTML文件的啟動腳本。 看到一個Runnable實例使用異步模塊定義與RequireJS,在示例應用程序一看。請注意,但是,示例應用程序只是一個非常基本的(即,不生產質量)的例子。
新聞熱點
疑難解答