AngularJs & UI 路由器 - 子模块在其父模块之前被注册?
AngularJs & UI Router - submodule is being registered before it's parent module?
我正在使用 ui 路由器来管理路由,包括用于子模块。
父子目录结构如下:
管理员
|
| ---buildteams
| |
| |--- buildteams.js
| |--- buildteams.tpl.html
|--- admin.js
|--- admin.tpl.html
admin.js 看起来像这样:
(function(adminModule) {
adminModule.config(function ($stateProvider) {
$stateProvider
.state('admin', {
url: '/admin',
views: {
"main": {
controller: 'AdminController as vm',
templateUrl: 'admin/admin.tpl.html'
}
},
data:{ pageTitle: 'Administration' }})
.state('admin.buildteams', {
url: '/buildteams',
views: {
"main": {
controller: 'AdminController as vm',
templateUrl: 'admin/admin.tpl.html'
}
},
data:{ pageTitle: 'Build Teams' }
});
});
adminModule.controller('AdminController', function ($scope,
$modal,
$state) {
var vm = this;
vm.itemSelected = function(item){
if(item)
{
vm.template = item.template;
vm.selected = {};
vm.selected[item.name] = true;
}
};
var init = function(vm) {
vm.menuItems = [
{
name: "Build Teams",
href: "admin.buildteams",
template: "admin/buildteams/buildteams.tpl.html"
}
];
var current = $state.current.name;
var item = vm.menuItems.find(function(x){
return x.href===current;
});
vm.itemSelected(item);
};
init(vm);
});}(angular.module("myApp.admin", ['ui.router'])));
buildteams.js 看起来像这样:
(function(adminModule) {
adminModule.controller('AdminBuildTeamsController', function ($scope,$modal) {
var vm = this;
var init = function(vm) {
};
init(vm);
});}(angular.module("myApp.admin")));
这是我注册模块的地方:
(function(app) {
//configure routing
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
})
//inject http provider with authorization header
.config(function($httpProvider) {
$httpProvider.interceptors.push(
function($q, cachedUserService) {
return {
'request': function(config) {
//ditch if the url is not api
var user = cachedUserService.getCurrentUser();
if (user) {
config.headers["Authorization"] = user.token;
}
return config || $q.when(config);
}
};
}
);
}
);
//register directives
app.directive("verticalMenu", function(){
return {
restrict: "E",
templateUrl: "partialtemplates/verticalmenu.tpl.html"
};
});
//not sure what this is
app.run(function () {});
//main controller
app.controller('AppController', function ($scope,
cachedUserService,
$modal,
userAccountService,
$location) {
$scope.pageTitle = "myApp";
$scope.user = cachedUserService.getCurrentUser();
$scope.showLoginDialog = function()
{
var modalInstance = $modal.open({
templateUrl: 'loginDialogContent.html',
controller: 'LoginDialogController',
windowClass: 'app-modal-window'
});
$scope.loginDialogOpened = true;
modalInstance.result.then(function (user) {
$scope.user = user;
cachedUserService.setRememberEmail($scope.user.email);
}, function () {
});
};
if($scope.user == null)
{
$scope.user = {
loggedIn : false
};
}
//app controller watches
$scope.$watch('user', function(newVal, oldVal){
if(oldVal.loggedIn != newVal.loggedIn)
{
$scope.$broadcast('userLoggedIn', newVal);
}
});
$scope.logout = function()
{
userAccountService.logout();
$scope.user = {
loggedIn : false
};
$location.path("/home");
};
$scope.unauthorizedNavigation = function(desiredPath)
{
$location.path("/home");
$scope.showLoginDialog();
};
$scope.loginDialogOpened = false;
});}(angular.module("myApp", [
'myApp.home',
'myApp.about',
'myApp.useradmin',
'myApp.admin',
'templates-app',
'templates-common',
'ui.router.state',
'ui.router',
'ui.bootstrap'
])));
当我尝试 build 时,出现此错误:
Error: [$injector:nomod] Module 'myApp.admin' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.2.28/$injector/nomod?p0=myApp.admin
at /Users/richard/Projects/myAppFrontEnd/vendor/angular/angular.js:78
Firefox 35.0.0 (Mac OS X 10.9): Executed 0 of 0 ERROR (0.272 secs / 0 secs)
我追踪它并发现 angular 试图注册 buildteams
子模块 在 它注册 admin
模块之前。所以 admin
模块不在那里添加 buildteams
子模块。
需要注意的一件事...此确切代码在同一应用程序的另一种情况下有效。事实上,这段 module/submodule 代码是从同一项目中的 useradmin 文件复制而来的。 (请参阅上面我注册 useradmin
和 admin
.
的模块注册
有什么想法吗?怎么回事?
angular 以什么顺序加载模块?有什么方法可以指定该顺序吗?
编辑
这是父模块的 html:
(function(adminModule) {
adminModule.config(function ($stateProvider) {
$stateProvider
.state('admin', {
url: '/admin',
views: {
"main": {
controller: 'AdminController as vm',
templateUrl: 'admin/admin.tpl.html'
}
},
data:{ pageTitle: 'Administration' }})
.state('admin.buildteams', {
url: '/buildteams',
views: {
"main": {
controller: 'AdminController as vm',
templateUrl: 'admin/admin.tpl.html'
}
},
data:{ pageTitle: 'Build Teams' }
});
});
adminModule.controller('AdminController', function ($scope,
$modal,
$state) {
var vm = this;
vm.itemSelected = function(item){
if(item)
{
vm.template = item.template;
vm.selected = {};
vm.selected[item.name] = true;
}
};
var init = function(vm) {
vm.menuItems = [
{
name: "Build Teams",
href: "admin.buildteams",
template: "admin/buildteams/buildteams.tpl.html"
}
];
var current = $state.current.name;
var item = vm.menuItems.find(function(x){
return x.href===current;
});
vm.itemSelected(item);
};
init(vm);
});}(angular.module("myApp.admin", [
'ui.router'])));
这是子模块的 html:
<div ng-controller="AdminBuildTeamsController as sub">
Hello World!
</div>
根据我们的聊天讨论,问题出在浏览器/karma 加载文件的顺序上。 Grunt 用于查找所有 .js 文件,它会尝试首先解析子模块文件,因为文件夹名称按字母顺序排列在主 .js 文件之前。
所以运行
angular.module("myApp.admin")
之前
angular.module("myApp.admin", [])
导致了这个问题。 Grunt 已设置为加载所有 js 文件,但加载顺序错误。一种解决方案是重命名文件以使顺序正确。
我正在使用 ui 路由器来管理路由,包括用于子模块。
父子目录结构如下:
管理员
|
| ---buildteams
| |
| |--- buildteams.js
| |--- buildteams.tpl.html
|--- admin.js
|--- admin.tpl.html
admin.js 看起来像这样:
(function(adminModule) {
adminModule.config(function ($stateProvider) {
$stateProvider
.state('admin', {
url: '/admin',
views: {
"main": {
controller: 'AdminController as vm',
templateUrl: 'admin/admin.tpl.html'
}
},
data:{ pageTitle: 'Administration' }})
.state('admin.buildteams', {
url: '/buildteams',
views: {
"main": {
controller: 'AdminController as vm',
templateUrl: 'admin/admin.tpl.html'
}
},
data:{ pageTitle: 'Build Teams' }
});
});
adminModule.controller('AdminController', function ($scope,
$modal,
$state) {
var vm = this;
vm.itemSelected = function(item){
if(item)
{
vm.template = item.template;
vm.selected = {};
vm.selected[item.name] = true;
}
};
var init = function(vm) {
vm.menuItems = [
{
name: "Build Teams",
href: "admin.buildteams",
template: "admin/buildteams/buildteams.tpl.html"
}
];
var current = $state.current.name;
var item = vm.menuItems.find(function(x){
return x.href===current;
});
vm.itemSelected(item);
};
init(vm);
});}(angular.module("myApp.admin", ['ui.router'])));
buildteams.js 看起来像这样:
(function(adminModule) {
adminModule.controller('AdminBuildTeamsController', function ($scope,$modal) {
var vm = this;
var init = function(vm) {
};
init(vm);
});}(angular.module("myApp.admin")));
这是我注册模块的地方:
(function(app) {
//configure routing
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
})
//inject http provider with authorization header
.config(function($httpProvider) {
$httpProvider.interceptors.push(
function($q, cachedUserService) {
return {
'request': function(config) {
//ditch if the url is not api
var user = cachedUserService.getCurrentUser();
if (user) {
config.headers["Authorization"] = user.token;
}
return config || $q.when(config);
}
};
}
);
}
);
//register directives
app.directive("verticalMenu", function(){
return {
restrict: "E",
templateUrl: "partialtemplates/verticalmenu.tpl.html"
};
});
//not sure what this is
app.run(function () {});
//main controller
app.controller('AppController', function ($scope,
cachedUserService,
$modal,
userAccountService,
$location) {
$scope.pageTitle = "myApp";
$scope.user = cachedUserService.getCurrentUser();
$scope.showLoginDialog = function()
{
var modalInstance = $modal.open({
templateUrl: 'loginDialogContent.html',
controller: 'LoginDialogController',
windowClass: 'app-modal-window'
});
$scope.loginDialogOpened = true;
modalInstance.result.then(function (user) {
$scope.user = user;
cachedUserService.setRememberEmail($scope.user.email);
}, function () {
});
};
if($scope.user == null)
{
$scope.user = {
loggedIn : false
};
}
//app controller watches
$scope.$watch('user', function(newVal, oldVal){
if(oldVal.loggedIn != newVal.loggedIn)
{
$scope.$broadcast('userLoggedIn', newVal);
}
});
$scope.logout = function()
{
userAccountService.logout();
$scope.user = {
loggedIn : false
};
$location.path("/home");
};
$scope.unauthorizedNavigation = function(desiredPath)
{
$location.path("/home");
$scope.showLoginDialog();
};
$scope.loginDialogOpened = false;
});}(angular.module("myApp", [
'myApp.home',
'myApp.about',
'myApp.useradmin',
'myApp.admin',
'templates-app',
'templates-common',
'ui.router.state',
'ui.router',
'ui.bootstrap'
])));
当我尝试 build 时,出现此错误:
Error: [$injector:nomod] Module 'myApp.admin' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument. http://errors.angularjs.org/1.2.28/$injector/nomod?p0=myApp.admin at /Users/richard/Projects/myAppFrontEnd/vendor/angular/angular.js:78 Firefox 35.0.0 (Mac OS X 10.9): Executed 0 of 0 ERROR (0.272 secs / 0 secs)
我追踪它并发现 angular 试图注册 buildteams
子模块 在 它注册 admin
模块之前。所以 admin
模块不在那里添加 buildteams
子模块。
需要注意的一件事...此确切代码在同一应用程序的另一种情况下有效。事实上,这段 module/submodule 代码是从同一项目中的 useradmin 文件复制而来的。 (请参阅上面我注册 useradmin
和 admin
.
有什么想法吗?怎么回事?
angular 以什么顺序加载模块?有什么方法可以指定该顺序吗?
编辑
这是父模块的 html:
(function(adminModule) {
adminModule.config(function ($stateProvider) {
$stateProvider
.state('admin', {
url: '/admin',
views: {
"main": {
controller: 'AdminController as vm',
templateUrl: 'admin/admin.tpl.html'
}
},
data:{ pageTitle: 'Administration' }})
.state('admin.buildteams', {
url: '/buildteams',
views: {
"main": {
controller: 'AdminController as vm',
templateUrl: 'admin/admin.tpl.html'
}
},
data:{ pageTitle: 'Build Teams' }
});
});
adminModule.controller('AdminController', function ($scope,
$modal,
$state) {
var vm = this;
vm.itemSelected = function(item){
if(item)
{
vm.template = item.template;
vm.selected = {};
vm.selected[item.name] = true;
}
};
var init = function(vm) {
vm.menuItems = [
{
name: "Build Teams",
href: "admin.buildteams",
template: "admin/buildteams/buildteams.tpl.html"
}
];
var current = $state.current.name;
var item = vm.menuItems.find(function(x){
return x.href===current;
});
vm.itemSelected(item);
};
init(vm);
});}(angular.module("myApp.admin", [
'ui.router'])));
这是子模块的 html:
<div ng-controller="AdminBuildTeamsController as sub">
Hello World!
</div>
根据我们的聊天讨论,问题出在浏览器/karma 加载文件的顺序上。 Grunt 用于查找所有 .js 文件,它会尝试首先解析子模块文件,因为文件夹名称按字母顺序排列在主 .js 文件之前。
所以运行
angular.module("myApp.admin")
之前
angular.module("myApp.admin", [])
导致了这个问题。 Grunt 已设置为加载所有 js 文件,但加载顺序错误。一种解决方案是重命名文件以使顺序正确。