angularjs学习笔记——使用requirejs动态注入控制器

前端之家收集整理的这篇文章主要介绍了angularjs学习笔记——使用requirejs动态注入控制器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

最近一段时间在学习angularjs,由于觉得直接使用它需要加载很多的js文件,因此想使用requirejs来实现异步加载,并动态注入控制器。简单搜索了下发现好多教程写的都很复杂,所以打算写一下我的方法,算是学习笔记了。

demo目录如下图:

index.html文件内容

  1. <!-- index.html -->
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <Meta charset="UTF-8">
  6. <title>demo</title>
  7. <!-- 引入requirejs,并在main.js中初始化 -->
  8. <script data-main="main.js" src="libs/require.js">
  9. </script>
  10. </head>
  11. <body>
  12. <div ng-view></div>
  13. </body>
  14. </html>

在引入main.js后,就需要在其中完成requirejs的初始化:

  1. // main.js
  2.  
  3. 'use strict';
  4.  
  5. (function (win) {
  6. require.config({
  7. baseUrl: './',// 依赖相对路径
  8. paths: {
  9. 'angular': 'libs/angular.min','angular-route': 'libs/angular-route.min'
  10. },// 引入没有使用requirejs模块写法的类库
  11. shim: {
  12. 'angular': {
  13. exports: 'angular'
  14. },'angular-route': {
  15. // angular-route依赖angular
  16. deps: ['angular'],exports: 'ngRoute'
  17. }
  18. }
  19. });
  20. // 自动导入router.js模块,由于后缀名可以省略,故写作'router',// 并将模块返回的结果赋予到router中。
  21. require(['angular','router'],function(angular,router){
  22. // 手动启动angularjs,特别说明此处的bootstrap不是那个ui框架,
  23. // 而是angularjs的一个手动启动框架的函数
  24. angular.bootstrap(document,['blogApp']);
  25. });
  26. })(window);

main.js中完成了各模块的初始化,并且引入了router.js
下面我们在router.js中配置路由:

  1. // router.js
  2.  
  3. define(['angular','require','angular-route'],function (angular,require) {
  4.  
  5. var blogApp = angular.module('blogApp',['ngRoute']);
  6.  
  7. blogApp.config(['$routeProvider','$controllerProvider',function($routeProvider,$controllerProvider) {
  8. $routeProvider
  9. .when('/',{
  10. templateUrl:'templates/list.html',controller: 'ListCtrl',resolve:{
  11. delay : ctrlRegister('ListCtrl',['controllers/ListCtrl.js'])
  12. }
  13. })
  14. .when('/data',{
  15. templateUrl:'templates/data.html',controller: 'DataCtrl',resolve:{
  16. delay : ctrlRegister('DataCtrl',['controllers/DataCtrl.js'])
  17. }
  18. })
  19. .otherwise({
  20. redirectTo: '/'
  21. });
  22.  
  23. function ctrlRegister (ctrlName,ctrlModule) {
  24. return function ($q) {
  25. var defer = $q.defer();
  26. require(ctrlModule,function (controller) {
  27.  
  28. $controllerProvider.register(ctrlName,controller);
  29.  
  30. defer.resolve();
  31. });
  32. return defer.promise;
  33. }
  34. }
  35. }
  36. ]);
  37.  
  38. return blogApp;
  39. });

我把这里面拆为分三个部分来说
第一部分:定义该模块

  1. // 引入3个基础模块
  2. define(['angular',require) {
  3. // 定义整个demo为一个名为blogApp的模块
  4. var blogApp = angular.module('blogApp',['ngRoute']);
  5. // ...第二部分:路由配置...
  6. // ...第三部分:复用的动态注入控制器函数
  7. // 向main.js返回这个blogApp
  8. return blogApp;
  9. });

第二部分:设置基础路由

  1. blogApp.config(['$routeProvider',{
  2. // 模板地址
  3. templateUrl:'templates/list.html',// 控制器的名字
  4. controller: 'ListCtrl',// resolve用来在完成路由前处理一些事
  5. // 这里用来动态加载并注入相应的控制器
  6. resolve:{
  7. // ctrlRegister为我自己写的一个复用的函数
  8. // 用于注入控制器。见第三部分
  9. delay : ctrlRegister('ListCtrl',['controllers/ListCtrl.js'])
  10. }
  11. });
  12. }
  13. }

第三部分:复用的控制器注入函数

  1. // 该函数接受两个参数
  2. // ctrlName,字符串类型,为该控制器的名字
  3. // ctrlModule,字符串数组类型,为要引入的控制器的相对地址
  4. // 调用例如 ctrlRegister('ListCtrl',['controllers/ListCtrl.js'])
  5. function ctrlRegister (ctrlName,ctrlModule) {
  6.  
  7. return function ($q) {
  8. var defer = $q.defer();
  9. // 加载该控制器,并将返回值赋给controller,返回值一般是一个控制器函数
  10. require(ctrlModule,function (controller) {
  11. // 将返回值注册名称为ctrlName的控制器
  12. $controllerProvider.register(ctrlName,controller);
  13.  
  14. defer.resolve();
  15. });
  16. // 完成注册
  17. return defer.promise;
  18. }
  19. }

好了,这样就完成了动态加载的功能了,下面就可以写要动态加载的控制器了
用其中一个控制器ListCtrl.js来说明问题:

  1. // ListCtrl.js
  2.  
  3. // 加载angular模块
  4. define(['angular'],function (angular) {
  5. 将本控制器函数作为结果返回给router.js
  6. return function ListCtrl( $scope ){
  7. $scope.lists = ['1','2','3'];
  8. };
  9. });

剩下的事情就是在list.html中接收控制器传送的数据了:

  1. <!-- list.html -->
  2. <ul>
  3. <li ng-repeat="list in lists"><a href="#/{{list}}" ng-bind="list"></a></li>
  4. </ul>

最终实现的功能是:
比如我访问http://127.0.0.1/demo/#/只会加载list.htmlListCtrl.js
而当访问http://127.0.0.1/demo/#/data就只会加载data.htmlDataCtrl.js。这样做有什么好处呢?当有很多控制器时,可以按需加载相应的控制器,不会一股脑全部加载上来(看起来依然并没有什么卵用)。很惭愧,只为大家节约了一点微小的带宽,谢谢大家。

猜你在找的Angularjs相关文章