一般情况下我们会将项目所用到的controller/directive/filter/sercive预先加载完再初始化AngularJS模块,但是当项目比较复杂的情况下,应该是打开对应的界面才加载对应的controller等资源,但是AngularJS一旦初始化,之后加载的controller/directive/filter/sercive是不会自动注册到模块上的。用AngularJS + ui-router + RequireJS来构建项目应该是比较常见的,所以我就基于这个条件来看看如何解决这个问题。

目录结构:

HTML结构非常简单,两个链接,分别改变路由切换到不同子页面:

<html>
<head>
<title>AngularJS + ui-router + RequireJS异步加载注册controller</title>
</head>
<body>
<a href="#home">home</a>
<a href="#local">local</a>
<div ui-view></div>
<script type="text/javascript" src="js/require.js" data-main="js/main"></script>
</body>
</html>

main.js配置文件路径,初始化模块

require.config({
baseUrl: 'js',
paths: {
'app': 'app',
'angular': 'angular.min',
'router': 'angular-ui-router'
},
shim: {
'router': {
deps: ['angular']
}
}
})
// 手动初始化myModule模块
require(['app'],function(){
angular.bootstrap(document, ['myModule'])
})

app.js配置路由并返回myModule模块

define(['router'],function(){
var app = angular.module("myModule", ['ui.router'])
.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('home');
$stateProvider
.state("home",{
url:"/home",
template: '<p>这里是home页面</p>'
})
.state("local",{
url:"/local",
template: '<p>这里是local页面</p>'
})
})
  return app;
})

界面如下,现在可以点击home和local切换到对应的子页面

接下来要做的是,切换到home界面要加载homeCtrl控制器,切换到local页面加载localCtrl控制器,我们将会用到$controllerProvider来手动注册控制器。怎么拿到$controllerProvider到引用呢?

对angular应用来说,模块对象是全局的,正好可以用来保存$controllerProvider的引用

在app.js文件define内部加上以下代码

app.config(function($controllerProvider,$compileProvider,$filterProvider,$provide){
app.register = {
//得到$controllerProvider的引用
controller : $controllerProvider.register,
//同样的,这里也可以保存directive/filter/service的引用
directive: $compileProvider.directive,
filter: $filterProvider.register,
service: $provide.service
};
})

接着在路由中配置要加载的控制器/指令/过滤器/服务

.config(['$stateProvider','$urlRouterProvider',function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('home');
$stateProvider
.state("home",{
url:"/home",
controller: 'homeCtrl',
template: '<p>{{str}}</p>',
resolve: {
loadCtrl: ["$q", function($q) {
var deferred = $q.defer();
//异步加载controller/directive/filter/service
require([
'controller/homeCtrl'
], function() { deferred.resolve(); });
return deferred.promise;
}]
}
})
.state("local",{
url:"/local",
controller: 'localCtrl',
template: '<p>{{str}}</p>',
resolve: {
loadCtrl: ["$q", function($q) {
var deferred = $q.defer();
//异步加载controller/directive/filter/service
require([
'controller/localCtrl'
], function() { deferred.resolve(); });
return deferred.promise;
}]
}
})
}])

最后是控制器的写法,为了省事就两个写在一块了

define(['app'],function(app){
app.register
.controller('homeCtrl', function($scope){
$scope.str = 'home page';
})
app.register
.controller('localCtrl',function($scope){
$scope.str = 'local page'
})
})

刷新页面, 就可以动态加载controller了。

directive/filter/service的写法类似于controller,不再赘述,自己动手丰衣足食。实例放在git上

3月21日更新:分别写了controller、filter、Service、directive的简单实例放到git上了

By:古德God于 2016/01/15 00:30:47

原文链接:http://www.cnblogs.com/wangmeijian/p/5020788.html

AngularJS + ui-router + RequireJS异步加载注册controller/directive/filter/service的更多相关文章

  1. AngularJS 实现按需异步加载

    习惯了 seajs 的异步加载方式,也想着 angular 也能同样使用异步加载,但是事实不随人愿. angularjs 和 requirejs 一样,使用的是预先加载的方式组织模块(这和 seajs ...

  2. Vue中router路由异步加载组件-优化性能

    何时使用异步加载组件 当首页app.js文件太大时,可以拆分组件异步加载,如果app.js文件很小时,不建议使用异步加载组件,因为异步加载组件时每次都要发送一个HTTP请求,这样的代价远比首页一次性加 ...

  3. 【Ajax】实现注册页面判断用户名是否可用的提示—异步加载

    效果如图 在注册或登录网站时,当我们输入错误格式的账号或信息时,会看到这种提示. 那怎么实现呢,通过ajax异步加载的方式,可以实现不刷新页面就显示出该提示. 实现 首先创建一个JSP,写一个简单的页 ...

  4. 玩转Web之easyui(二)-----easy ui 异步加载生成树节点(Tree),点击树生成tab(选项卡)

    关于easy ui 异步加载生成树及点击树生成选项卡,这里直接给出代码,重点部分代码中均有注释 前台: $('#tree').tree({ url: '../servlet/School_Tree?i ...

  5. WPF 多线程 UI:设计一个异步加载 UI 的容器

    对于 WPF 程序,如果你有某一个 UI 控件非常复杂,很有可能会卡住主 UI,给用户软件很卡的感受.但如果此时能有一个加载动画,那么就不会感受到那么卡顿了.UI 的卡住不同于 IO 操作或者密集的 ...

  6. [转]C#通过委托更新UI(异步加载)

    我们在使用 windowform 编程的时候,我们或许可能会越到,各种在窗体加载的时候,会进行其他的操作: 1.如果是在加载之前进行其它操作,则整个界面出来的很慢,而且若是时间长的话,页面很久才能出来 ...

  7. 关于requireJS的同步加载和异步加载

    这篇随笔主要记录require('name')和require(['name1','name2'])在同步和异步加载使用的区别 1.require('name')同步加载模块的形式 define(fu ...

  8. 【requireJS源码学习03】细究requireJS的加载流程

    前言 这个星期折腾了一周,中间没有什么时间学习,周末又干了些其它事情,这个时候正好有时间,我们一起来继续学习requireJS吧 还是那句话,小钗觉得requireJS本身还是有点难度的,估计完全吸收 ...

  9. Android开发--异步加载

    因为移动端软件开发思维模式或者说是开发的架构其实是不分平台和编程语言的,就拿安卓和IOS来说,他们都是移动前端app开发展示数据和用户交互数据的数据终端,移动架构的几个大模块:UI界面展示.本地数据可 ...

随机推荐

  1. Eclipse安装与使用

    Step1:启动Eclipse,在菜单中选择“文件 --> 新建 --> Java项目”,弹出对话框: Step2:填入项目名称,点击“完成”,创建项目成功,可以看到在 E:\java\w ...

  2. linux命令总结之echo命令

    echo是一种最常用的与广泛使用的内置于Linux的bash和C shell的命令,通常用在脚本语言和批处理文件中来在标准输出或者文件中显示一行文本或者字符串. echo命令的语法是: echo [选 ...

  3. Centos6.6下编译安装Apache2.2.31

    安装环境: [root@apache ~]# cat /etc/redhat-release CentOS release 6.6 (Final) [root@apache ~]# uname -r ...

  4. Python3.x文件处理详解

    Python3.x文件处理详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 任何一门语言都有其特有的操作文件的方式,Python2.x版本有两种操作文件的方式,没错就是open函 ...

  5. CSS 设置网页中选中文字的背景色

    在样式文件中增加如下代码: ::selection { background: hsla(5, 92%, 76%, 0.8); color: #fff;}

  6. select遍历list默认选中初始值

    <select id="userstatus" name="userstatus">         <c:forEach items=&qu ...

  7. Zephir入门教程一

    一.如何安装 zephir-安装和初体验:http://blog.csdn.net/u011142688/article/details/51619811 二.如何使用 需要切到工作目录下,也就是co ...

  8. Android View坐标系详解(getTop()、getX、getTranslationX...)

    View 提供了如下 5 种方法获取 View 的坐标:1. View.getTop().View.getLeft().View.getBottom().View.getRight();2. View ...

  9. js 加alert后才能执行方法

    原因是:访问页面时,某些js方法还没初始化(或者还没有加载出来)此时调用肯定不执行.alert起到了延迟的功能,当用户点击确定此时要执行的js恰好初始化完成,能正常执行. 解决方法是 加setTime ...

  10. django Rest Framework---缓存通过drf-extensions扩展来实现

    什么情况下使用缓存 1.不经常更新的数据 2.用户经常访问的一些页面,比如商品列表页.商品详情页等 3.用户经常修改的一些操作:购物车.订单中心等 关于DRF缓存扩展可以参考文档:http://chi ...