您的位置:首页 > Web前端 > AngularJS

AngularJS + ui-router + RequireJS异步加载注册controller/directive/filter/service

2016-01-15 09:04 721 查看
一般情况下我们会将项目所用到的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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: