AngularJS + ui-router + RequireJS异步加载注册controller/directive/filter/service
一般情况下我们会将项目所用到的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的更多相关文章
- AngularJS 实现按需异步加载
习惯了 seajs 的异步加载方式,也想着 angular 也能同样使用异步加载,但是事实不随人愿. angularjs 和 requirejs 一样,使用的是预先加载的方式组织模块(这和 seajs ...
- Vue中router路由异步加载组件-优化性能
何时使用异步加载组件 当首页app.js文件太大时,可以拆分组件异步加载,如果app.js文件很小时,不建议使用异步加载组件,因为异步加载组件时每次都要发送一个HTTP请求,这样的代价远比首页一次性加 ...
- 【Ajax】实现注册页面判断用户名是否可用的提示—异步加载
效果如图 在注册或登录网站时,当我们输入错误格式的账号或信息时,会看到这种提示. 那怎么实现呢,通过ajax异步加载的方式,可以实现不刷新页面就显示出该提示. 实现 首先创建一个JSP,写一个简单的页 ...
- 玩转Web之easyui(二)-----easy ui 异步加载生成树节点(Tree),点击树生成tab(选项卡)
关于easy ui 异步加载生成树及点击树生成选项卡,这里直接给出代码,重点部分代码中均有注释 前台: $('#tree').tree({ url: '../servlet/School_Tree?i ...
- WPF 多线程 UI:设计一个异步加载 UI 的容器
对于 WPF 程序,如果你有某一个 UI 控件非常复杂,很有可能会卡住主 UI,给用户软件很卡的感受.但如果此时能有一个加载动画,那么就不会感受到那么卡顿了.UI 的卡住不同于 IO 操作或者密集的 ...
- [转]C#通过委托更新UI(异步加载)
我们在使用 windowform 编程的时候,我们或许可能会越到,各种在窗体加载的时候,会进行其他的操作: 1.如果是在加载之前进行其它操作,则整个界面出来的很慢,而且若是时间长的话,页面很久才能出来 ...
- 关于requireJS的同步加载和异步加载
这篇随笔主要记录require('name')和require(['name1','name2'])在同步和异步加载使用的区别 1.require('name')同步加载模块的形式 define(fu ...
- 【requireJS源码学习03】细究requireJS的加载流程
前言 这个星期折腾了一周,中间没有什么时间学习,周末又干了些其它事情,这个时候正好有时间,我们一起来继续学习requireJS吧 还是那句话,小钗觉得requireJS本身还是有点难度的,估计完全吸收 ...
- Android开发--异步加载
因为移动端软件开发思维模式或者说是开发的架构其实是不分平台和编程语言的,就拿安卓和IOS来说,他们都是移动前端app开发展示数据和用户交互数据的数据终端,移动架构的几个大模块:UI界面展示.本地数据可 ...
随机推荐
- 洛谷P3302 森林
题意:给定森林,可以把两棵树连起来或者询问链上第k大. 解:启发式合并. 我一开始想到了启发式合并但是发现这样做之后一棵子树就不是一段连续的区间了,那就不能子树xxx了,很迷惘. 后来看了题解发现本来 ...
- Java 泛型类型基础
为什么要使用泛型? 未使用泛型的情况: // 创建列表类 List list = new ArrayList(); // 添加一个类型为 String 的列表元素 list.add("hel ...
- Spring RedisTemplate操作-xml配置(1)
网上没能找到全的spring redistemplate操作例子,故特意化了点时间做了接口调用练习,基本包含了所有redistemplate方法. 该操作例子是个系列,该片为spring xml配置, ...
- 利用itertools生成密码字典,多线程撞库破解rar压缩文件密码
脚本功能: 利用itertools生成密码字典(迭代器形式) 多线程并发从密码字典中取出密码进行验证 验证成功后把密码写入文件中保存 #!/usr/bin/env python # -*- codin ...
- if 语句 写了return 报错
- 基于滑动窗口协议写的程序(UDP实现) .
正好有一个大作业关于用socket实现滑动窗口协议,所以写了一个,模拟接收方与发送方窗口都是2,用两个线程实现. 下面是代码,注释的比较详细了. socket_udp.h #include<st ...
- Windows修改默认远程端口号3389
1.打开注册表:运行-regedit: 2.HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server\Wds\Repwd\ ...
- linux下查看各硬件型号
查看主板型号 # dmidecode |grep -A 8 "System Information"System Information 上网查DELL CS24-TY,找到说主板 ...
- Ansible 插件 之 【CMDB】【转】
Github地址: https://github.com/fboender/ansible-cmdb 从facts收集信息,生成主机概述 安装 wget https://github.com/fboe ...
- TFS报表管理器无权限访问的配置
刚接触TFS,有太多的功能不能知道怎么配置,今天想了解一下TFS的报表功能,当登录TFS后,点击项目中的“查看报表”