我也在想同样的事情,并决定走在狂野的一边,将所有内容合并到一个模块下。当然,几分钟后才知道为什么这不是一个好主意:) 所以我想花时间解释一下我认为模块在哪里发挥了非常好的作用,独立于“一般意见”。
我从以下方面着手:
// main.js - v0
var ServerData = require('./services/server-data')
var filters = require('./filters')
angular.module('ServerLoad', ['ngRoute'])
.factory('ServerData', ['$http', ServerData])
.filter('lastseen', function () {return filters.lastseen})
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.otherwise({
redirectTo: '/servers'
})
}])
现在我想添加一个显示服务器列表的视图。本质上,视图只不过是控制器和路由的组合,因此我将它们添加到代码中。这是我得到的(然后我会解释为什么这不是很好以及子模块如何解决这个问题):
// main.js - v1
var ServerListView = require('./views/server-list-view') // <-- import view
var ServerData = require('./services/server-data')
var filters = require('./filters')
angular.module('ServerLoad', ['ngRoute'])
.factory('ServerData', ['$http', ServerData])
.controller('ServerListCtrl', ['ServerData', ServerListView]) // <-- add controller
.filter('lastseen', function () {return filters.lastseen})
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/servers', { // <-- add route
controller: 'ServerListCtrl', //
controllerAs: 'servers', //
templateUrl: 'assets/partials/server-list.html' //
}) //
.otherwise({
redirectTo: '/servers'
})
}])
虽然这肯定是一个有效的设置,但我不喜欢的是main.js 定义了controllerAs 和templateUrl 属性。在我看来,这些属性真的应该在定义依赖它的代码的地方定义 --- './views/server-list-view',甚至可能在 ServerListView 类本身上。
因此,与您的 IIFE 有点类似,我向 ServerListView 添加了一个静态方法以将视图添加到模块:
// main.js - v2 (from v0)
var ServerListView = require('./views/server-list-view') // <-- import view
// ...
angular.module('ServerLoad', ['ngRoute'])
// ...
ServerListView.setup(window.angular.module('ServerLoad')) // <-- adds ctrl and route
和
// server-list-view.js - v2
function ServerListView (ServerData) {
var scope = this
// ...
}
module.exports = ServerListView
ServerListView.setup = function (module) {
module
.controller('ServerListCtrl', ['ServerData', ServerListView])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/servers', {
controller: 'ServerListCtrl',
controllerAs: 'servers',
templateUrl: 'assets/partials/server-list.html'
})
}])
}
我认为这看起来稍微好一些,但现在'ServerData' 的使用让我感到困扰。毕竟,它没有在任何地方的server-list-view.js 中声明。同样,如果视图需要一些额外的外部模块,我将不得不编辑 main.js 来添加它。这感觉不合适。
然后我突然想到,如果我可以编写一个 IIFE 以将 module 作为参数,为什么不让它以 angular 作为参数呢?然后它可以根据需要定义自己的模块并包含所需的所有依赖项。此外,如果您仍然热衷于单模块一切,那么只需使用 'ServerLoad' 模块名称并删除依赖项声明。这是唯一和全部的区别!
// server-list-view.js - v3
// ...
ServerListView.setup = function (angular) {
angular.module('ServerLoad.ServerListView', ['ngRoute', 'ServerLoad'])
// ...
}
所以,总而言之,我认为使用子模块的最大优势并不一定是其他人可以重用我的代码(我认为没有人会对我的服务器列表视图感兴趣),而是每一点代码可以独立存在,重用其他人的代码,而不需要主模块包含所有这些。 main.js 保持苗条,而 server-list-view.js 可以拉各种东西。
脚注。将ServerLoad 作为依赖项(到达ServerData 工厂)仍然看起来有点奇怪。当然,在版本 4 中,工厂也将存在于自己的子模块中;-)