一般情况下我们会将项目所用到的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. [转]Robotium环境搭建中的Errors running builder 'Android Resource Manag

    转自:http://blog.sina.com.cn/s/blog_68f262210102v75t.html 最近学习了Robotium测试框架,当然学习任何一个框架或是语言之前,第一步就是搭建环境 ...

  2. 多线程-----java基础知识总结

    一,关于线程的总体流程,如下图所示: 二,线程的常用方法:

  3. Java基础-hashMap原理剖析

    Java基础-hashMap原理剖析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.什么是哈希(Hash) 答:Hash就是散列,即把对象打散.举个例子,有100000条数 ...

  4. docker mysql authentication_string client does not support authentication 连接问题

    docker安装mysql后,本地navicat连接报错client does not support authentication 解决办法: 1. docker ps -a 查找到容器id 2.  ...

  5. Windows服务时间控件怎么调试

    写了timer,调试的话在构造函数里面把Elapsed方法写成null,null就可以调试了 public PSJCService() { InitializeComponent(); Getuser ...

  6. redis添加systemctl服务

    1.编辑systemctl服务配置文件 vim /lib/systemd/system/redis.service 2.内容如下 [Unit]Description=RedisAfter=networ ...

  7. WebSockets Tutorial(教程一)WebSockets简介

    一.WebSockets简介 以字面意思来说,握手可以被定义为两个人抓住和握手右手,象征着问候,祝贺,同意或告别.在计算机科学中,握手是确保服务器与客户端同步的过程.握手是Web Socket协议的基 ...

  8. 用到的设计模式总结--单例模式+工厂方法模式+Builder模式

    一,工厂方法模式和单例模式 工厂方法模式中有一个抽象的工厂接口和一个抽象的产品接口.然后,具体的工厂实现抽象工厂并负责生产具体的产品.由客户端决定 new 哪个具体的工厂,从而生产哪种产品. 因此,与 ...

  9. python 喜马拉雅 音乐下载 演示代码

    1.主程序文件 import os import json import requests from contextlib import closing from progressbar import ...

  10. 第11月第3天 直播 rtmp yuv

    1. LiveVideoCoreSDK AudioUnitRender ==> MicSource::inputCallback ==> GenericAudioMixer::pushBu ...