资讯专栏INFORMATION COLUMN

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

王军 / 2714人阅读

摘要:最近一段时间在学习,由于觉得直接使用它需要加载很多的文件,因此想使用来实现异步加载,并动态注入控制器。手动启动,特别说明此处的不是那个框架,而是的一个手动启动框架的函数中完成了各模块的初始化,并且引入了。

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

demo目录如下图:

index.html文件的内容:





    
    demo
    
    
    


    

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

// main.js

"use strict";

(function (win) {
    require.config({
        baseUrl: "./",
        // 依赖相对路径
        paths: {               
            "angular": "libs/angular.min",
            "angular-route": "libs/angular-route.min"
        },
        // 引入没有使用requirejs模块写法的类库
        shim: {
            "angular": {
                exports: "angular"
            },
            "angular-route": {
                // angular-route依赖angular
                deps: ["angular"],
                exports: "ngRoute"
            }
        }
    });
    
    // 自动导入router.js模块,由于后缀名可以省略,故写作"router",
    // 并将模块返回的结果赋予到router中。
    require(["angular","router"], function(angular,router){
        // 手动启动angularjs,特别说明此处的bootstrap不是那个ui框架,
        // 而是angularjs的一个手动启动框架的函数
        angular.bootstrap(document, ["blogApp"]);
    });
})(window);

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

// router.js

define(["angular", "require", "angular-route"], function (angular, require) {

    var blogApp = angular.module("blogApp",["ngRoute"]);

    blogApp.config(["$routeProvider","$controllerProvider",
        function($routeProvider,$controllerProvider) {
            $routeProvider
            .when("/", {
                templateUrl:"templates/list.html",
                controller: "ListCtrl",
                resolve:{
                    delay : ctrlRegister("ListCtrl",["controllers/ListCtrl.js"])
                }
            })
            .when("/data", {
                templateUrl:"templates/data.html",
                controller: "DataCtrl",
                resolve:{
                    delay : ctrlRegister("DataCtrl",["controllers/DataCtrl.js"])
                }
            })
            .otherwise({
                redirectTo: "/"
            });

            function ctrlRegister (ctrlName, ctrlModule) {
                return function ($q) {
                    var defer = $q.defer();
                    require(ctrlModule, function (controller) {

                        $controllerProvider.register(ctrlName, controller);

                        defer.resolve();
                    });
                    return defer.promise;
                }
            }
        }
    ]);

    return blogApp;
});

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

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

第二部分:设置基础路由

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

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

// 该函数接受两个参数
// ctrlName,字符串类型,为该控制器的名字
// ctrlModule,字符串数组类型,为要引入的控制器的相对地址
// 调用例如 ctrlRegister("ListCtrl",["controllers/ListCtrl.js"])
function ctrlRegister (ctrlName, ctrlModule) {

    return function ($q) {
        var defer = $q.defer();
        // 加载该控制器,并将返回值赋给controller,返回值一般是一个控制器函数
        require(ctrlModule, function (controller) {
            // 将返回值注册为名称为ctrlName的控制器
            $controllerProvider.register(ctrlName, controller);

            defer.resolve();
        });
        // 完成注册
        return defer.promise;
    }
}

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

// ListCtrl.js

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

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


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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79208.html

相关文章

  • Angular 4 简单入门笔记

    摘要:首先,我们需要在入口页面的中配置根路径然后创建一个路由模块路由配置在主模块中导入配置好的路由模块而在页面中需要一个容器去承载上面代码中的定义了用户点击后的路由跳转,定义该路由激活时的样式类。 刚实习的时候用过AngularJS,那时候真的是连原生JavaScript都不会写,依样画葫芦做了几个管理后台。然后突然换项目了,AngularJS就不写了,感觉前前后后接触了一年多的Angula...

    whlong 评论0 收藏0
  • RequireJS学习笔记

    摘要:如果有疑惑的地方,欢迎讨论,我是初学,希望能切磋和得到指点加载会阻塞页面加载默认异步加载文件方法一把放到页面底部加载方法二支持定义全局相对路径方法一自定义属性指定网页程序的主模块文件定义整个网页代码的入口文件的相对位置,以后此文件 如果有疑惑的地方,欢迎讨论,我是初学,希望能切磋和得到指点; js加载会阻塞页面加载: //requirejs默认异步加载js文件; 方法一...

    hersion 评论0 收藏0
  • 前端资源系列(4)-前端学习资源分享&前端面试资源汇总

    摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...

    princekin 评论0 收藏0
  • require.js学习笔记

    摘要:他仅需简单地通过一个标签发起请求,是实现跨域服务调用一种公认手段。为了在中使用服务,须要将参数的值指定为。该示例中,的参数为,因此告诉将响应包裹到一个中 加载JavaScript文件 RequireJS的目的是鼓励代码的模块化,它使用了不同于传统script标签的脚本加载步骤。可以用它来加速、优化代码,但其主要目的还是为了代码的模块化。它鼓励在使用脚本时以module ID替代URL地...

    K_B_Z 评论0 收藏0
  • AngularJS学习笔记(2) --- 指令参数和scope绑定策略

    摘要:引言指令可以说是的核心,而其开发也是比较困难的,本文主要介绍指令的一些参数和的绑定策略。指令执行的优先级,用于多个指令同时作用于同一个元素时。改变父会影响指令,而改变指令不会影响父。在父和指令之间建立双向绑定。 引言 指令(Directive)可以说是 AngularJS 的核心,而其开发也是比较困难的,本文主要介绍指令的一些参数和scope的绑定策略。 参数 从 AngularJS ...

    AndroidTraveler 评论0 收藏0

发表评论

0条评论

王军

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<