如何在我的AngularJS应用程序中添加require.js?
我的AngularJS应用程序中的控制器目前是这样编码的:
app.controller('appController',[ '$state','$timeout','enumService','userService','utilityService',appController ]); function appController( $scope,$state,$timeout,enumService,userService,utilityService ) { ... } 我想开始做的是使用require.js来处理控制器的延迟加载.我知道我应该使用这样的东西: require(["app"],function (app) { app.controller('appController',function appController( $scope,utilityService ) { ... }); }); 有人可以向我解释一下app.controller如何获得对服务的引用?我需要在require.js方面做任何其他事情吗?我正在跟踪我正在编写appController的方式吗?
TL;博士;最后一个解决方案是在最后一节,或者看看
this plunk
懒惰加载$注射器 angular-requirejs-seed项目说明如何通过设置如下这样的懒惰功能轻松实现延迟加载: define([],function() { return ['$scope','$http','myInjectable',function($scope,$http,myInjectable) { $scope.welcomeMessage = 'hey this is myctrl2.js!'; // because this has happened async,we've missed the digest cycle $scope.$apply(); }]; }); …然后实例化控制器,如下所示: .controller('MyCtrl2',['$scope','$injector',$injector) { require(['controllers/myctrl2'],function(myctrl2) { $injector.invoke(myctrl2,this,{'$scope': $scope}); }); ... 请注意,延迟加载的函数不是控制器.这只是一个使用$inject调用的函数,它允许它访问实际控制器的$范围,并允许它访问在你的应用程序中加载的任何注入. 您可以将相同的技术应用于服务,工厂或指令. 懒惰加载警告 在大多数情况下,延迟加载可能是自毁的.如果您的目标是为用户提供一个快速的网站,那么懒惰加载每个控制器是一个坏主意.一旦建立了HTTP连接,大多数互联网连接允许大量数据在短时间内流过电线.延迟,但是可以是真正的杀手.这就是为什么大多数网站这些天使用连接和缩小来打包他们的JavaScript并减少网络请求的数量,而不是依赖于延迟请求数量的延迟加载. 考虑你的应用程序的架构.您将创建多少个可重复使用的指令?在各种应用程序之间共享多少代码,不适合延迟加载?对于许多应用程序,大部分代码将由常见的组件组成,使得延迟加载毫无意义. 延迟加载在应用程序中是非常明确和分开的部分.那些非常独特和独立的片段可以被认为是单独的应用程序.然而,即使在这种情况下,您可能会考虑实际创建单独的应用程序,而不是组合它们
延迟装载架构 具有角度的惰性载荷相当复杂,因为角度不是设计用于支撑惰性载荷.在本节中,我将尝试引导您探索如何强制角度来支持延迟加载.这不是一个完整的解决方案,但我希望介绍在构建这样的应用程序时要了解的重要概念. 我们从路由器开始,而不是我在第一部分提出的angular-requirejs-seed,它实际上比延迟加载在你的应用程序的路由器中更有意义.使用ui-router,我们可以这样实现lazy-load: ... app.$controllerProvider = $controllerProvider; var lazyPartialDeferred; $stateProvider ... .state('lazy',{ url: "/lazy",templateProvider: function() { return lazyPartialDeferred.promise; },controller: 'lazyCtrl',resolve: { load: function($q,$templateCache) { var lazyCtrlDeferred = $q.defer(); lazyPartialDeferred = $q.defer(); require(['lazy'],function (lazy) { lazyCtrlDeferred.resolve(); lazyPartialDeferred.resolve($templateCache.get('lazy.html')); }); return lazyCtrlDeferred.promise; } } }); ... 我们在这里做的是推迟部分(lazy.html)和控制器(lazyCtrl)的实例化,直到我们的requirejs模块(lazy.js)被加载为止.另外,请注意,我们直接从$templateCache加载我们的view,partial,lazy.html.也就是说,当我们加载lazy.js时,部分本身就包含在lazy.js中.理论上,我们可以从lazy.js中单独加载lazy.html,但为了获得最佳性能,我们应该将部分文件编译成我们的js文件. 我们来看看lazy.js: define(['angular','lazy-partials'],function (angular) { var app = angular.module('app'); var lazyCtrl = ['$scope','$compile','$templateCache',function ($scope,$compile,$templateCache) { $scope.data = 'my data'; }]; app.$controllerProvider.register('lazyCtrl',lazyCtrl); }); 请记住,上述代码代表未编译的lazy.js.在生产中,lazy-partials.js(在上面的第一行引用)实际上将被编译成同一个文件. 现在我们来看看lazy-partials.js: // Imagine that this file was actually compiled with something like grunt-html2js // So,what you actually started with was a bunch of .html files which were compiled into this one .js file... define(['angular'],function (angular) { var $injector = angular.element(document).injector(),$templateCache = $injector.get('$templateCache'); $templateCache.put('lazy.html','<p>This is lazy content! and <strong>{{data}}</strong> <a href="#">go back</a></p>'); }); 再次,上述代码并不完全是这样的文件真正的样子. lazy-partials.js实际上将使用像grunt-html2js这样的构建工具插件从您的html文件自动生成. 现在,您可以在理论上使用迄今提出的方法构建整个应用程序.但是,这有点… janky.我们更喜欢在lazy.js中实例化一个新的模块,例如appLazy = angular.module(‘app.lazy’),然后实例化我们的控制器,指令,服务等,如appLazy.directive(…) . 然而,我们不能这样做的原因是因为所有这些东西都是在已经在lazy.js加载的时候已被调用的angular.bootstrap方法中初始化(并且提供给我们的应用程序).而且我们不能再重新调用angular.bootstrap(…).
那么,有没有办法懒散地实例化模块?是的,you can register a module and it’s sub-modules by iterating through various nested properties of the module object ( 本节中提供的大部分代码可在this plunker. (灵感来源未提及:Couch Potato,AngularAMD) 完整的懒惰加载解决方案: [ocLazyLoad ui-router requirejs] – plunk 因为ui路由器允许我们延迟加载模板和控制器,所以我们可以使用它与ocLazyLoad一起在路由更改之间即时加载模块.这个例子构建了上一节的原理,但是通过使用ocLazyLoad,我们有一个解决方案,可以使我们的延迟加载模块的结构与非惰性加载的模块相同. 这里的关键是我们的app.config(..)块: app.config(function($stateProvider,$locationProvider,$ocLazyLoadProvider) { var lazyDeferred; $ocLazyLoadProvider.config({ loadedModules: ['app'],asyncLoader: require }); $stateProvider ... .state('lazy',{ url: "/lazy",templateProvider: function() { return lazyDeferred.promise; },resolve: { load: function($templateCache,$ocLazyLoad,$q) { lazyDeferred = $q.defer(); return $ocLazyLoad.load({ name: 'app.lazy',files: ['lazy'] }).then(function() { lazyDeferred.resolve($templateCache.get('lazy.html')); }); } } }); ... lazy.js现在看起来像这样: define(['angular',function (angular) { var appLazy = angular.module('app.lazy',['app.lazy.partials']); appLazy.controller('lazyCtrl',$templateCache) { $scope.data = 'my data'; }); }); 请注意,这个文件在延迟加载方面已经不复存在了.您可以轻松地以非懒惰的方式加载该文件,并不会知道这个区别.同样的原则适用于lazy-partials.js: // Imagine that this file was actually compiled with something like grunt-html2js // So,function (angular) { angular.module('app.lazy.partials',[]) .run(function($templateCache) { $templateCache.put('lazy.html','<p>This is lazy content! and <strong>{{data}}</strong> <a href="#">go back</a></p>'); }); }); >>> check out the fully-functioning plunk< 部署 当涉及到部署,这个难题的最后一块是使用requirejs优化器来连接和最小化我们的js文件.理想情况下,我们希望优化器跳过已经包含在主应用程序中的依赖关系的连接(即:普通文件).为了完成这个,see this repo和build.js file. 一个更优雅的解决方案 我们可以通过为a very elegant solution添加一个ui路由器装饰器来改善以前的繁琐. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |