AngularJS模块声明的最佳实践?
我有一堆在我的应用程序中声明的Angular模块。 我最初开始用这样的“链接”语法来声明它们:
angular.module('mymodule', []) .controller('myctrl', ['dep1', function(dep1){ ... }]) .service('myservice', ['dep2', function(dep2){ ... }]) ... // more here
但是我认为这不是很容易阅读,所以我开始使用这样的模块variables来声明它们:
var mod = angular.module('mymodule', []); mod.controller('myctrl', ['dep1', function(dep1){ ... }]); mod.service('myservice', ['dep2', function(dep2){ ... }]); ...
第二种语法对我来说似乎更可读,但是我唯一的抱怨是这个语法在全局范围内留下了mod
variables。 如果我有其他一些名为mod
variables,它会被下一个variables覆盖(和其他与全局variables相关的问题)。
所以我的问题是,这是最好的方法吗? 或者做这样的事情会更好吗?
(function(){ var mod = angular.module('mymod', []); mod.controller('myctrl', ['dep1', function(dep1){ ... }]); mod.service('myservice', ['dep2', function(dep2){ ... }]); ... })();
或者它甚至不够重视? 只是想知道模块声明的“最佳实践”是什么。 提前致谢。
“最好”的方式来声明一个模块
由于angular是在全局作用域本身上,并且模块被保存到它的variables中,所以可以通过angular.module('mymod')
来访问模块:
// one file // NOTE: the immediately invoked function expression // is used to exemplify different files and is not required (function(){ // declaring the module in one file / anonymous function // (only pass a second parameter THIS ONE TIME as a redecleration creates bugs // which are very hard to dedect) angular.module('mymod', []); })(); // another file and/or another anonymous function (function(){ // using the function form of use-strict... "use strict"; // accessing the module in another. // this can be done by calling angular.module without the []-brackets angular.module('mymod') .controller('myctrl', ['dep1', function(dep1){ //.. }]) // appending another service/controller/filter etc to the same module-call inside the same file .service('myservice', ['dep2', function(dep2){ //... }]); // you can of course use angular.module('mymod') here as well angular.module('mymod').controller('anothermyctrl', ['dep1', function(dep1){ //.. }]) })();
没有其他全局variables是必需的。
当然,这取决于所有的喜好,但我认为这是最好的做法
- 你不必污染全球范围
- 你可以在任何地方访问你的模块,并随意将它们和它们的function分类到不同的文件
- 你可以使用“use strict”的函数forms;
- 文件的加载顺序并不重要
sorting模块和文件的选项
这种声明和访问模块的方式使你非常灵活。 您可以通过函数types(如另一个答案中所述)或通过路由对模块进行sorting,例如:
/******** sorting by route **********/ angular.module('home')... angular.module('another-route')... angular.module('shared')...
最后如何分类是个人品味和项目规模和types的问题。 我个人喜欢将同一个文件夹内的所有文件(命令,控制器,服务和filter的子文件夹)分组,包括所有不同的testing文件,因为它使得你的模块更加可重用。 因此,在中等规模的项目中,我最终得到了一个基本模块,其中包括所有基本路线及其控制器,服务,指令和或多或less复杂的子模块,当我认为它们也可以用于其他项目时,例如:
/******** modularizing feature-sets **********/ /controllers /directives /filters /services /my-map-sub-module /my-map-sub-module/controllers /my-map-sub-module/services app.js ... angular.module('app', [ 'app.directives', 'app.filters', 'app.controllers', 'app.services', 'myMapSubModule' ]); angular.module('myMapSubModule',[ 'myMapSubModule.controllers', 'myMapSubModule.services', // only if they are specific to the module 'myMapSubModule.directives', 'myMapSubModule.filters' ]);
对于非常大的项目,我有时最终会按照上面所描述的路由分组模块,或者通过一些选定的主路由,甚至路由组合和一些选定的组件,但是这取决于实际情况。
编辑:只是因为它是相关的,我碰到了最近再次: 保持谨慎,你只创build一个模块 (通过添加第二个参数angular.module函数)。 这会弄乱你的应用程序,可能很难察觉。
2015 EDITsorting模块:一年半的angular度体验后,我可以补充说,在你的应用程序中使用不同命名模块的好处是有限的,因为AMD仍然不能很好地与Angular和服务,指令和filter无论如何都是在angular上下文中全局可用的( 如这里所例示的 )。 尽pipe如此,仍然有语义和结构上的好处,并且可能有助于能够用一行代码来注释或排除一个模块。
按types分开子模块 (例如'myMapSubModule.controllers')几乎没有什么意义,因为它们通常是相互依赖的。
我喜欢Johnpapa的angular度引导,这里有一些与这个问题有关的规则:
规则:命名vs匿名函数
避免使用匿名函数:
// dashboard.js angular .module('app') .controller('Dashboard', function() { })
相反,使用命名函数:
// dashboard.js angular .module('app') .controller('Dashboard', Dashboard); function Dashboard() { }
正如作者所说: This produces more readable code, is much easier to debug, and reduces the amount of nested callback code.
规则:为每个文件定义1个组件。
避免一个文件中有多个组件:
angular .module('app', ['ngRoute']) .controller('SomeController', SomeController) .factory('someFactory', someFactory); function SomeController() { } function someFactory() { }
Intead,使用一个文件来定义模块:
// app.module.js angular .module('app', ['ngRoute']);
一个文件只是使用模块来定义一个组件
// someController.js angular .module('app') .controller('SomeController', SomeController); function SomeController() { }
另一个文件来定义另一个组件
// someFactory.js angular .module('app') .factory('someFactory', someFactory); function someFactory() { }
当然,还有很多模块,控制器和服务的规则是非常有用的,值得一读。
感谢ya_dimon的评论,上面的代码应该被包装在IIFE中,例如:
(function (window, angular) { angular.module('app') .controller('Dashboard', function () { }); })(window, window.angular);
我最近也有这个难题。 我已经像使用链式语法一样开始了,但是从长远来看,对于大型项目来说,这将变得很笨拙。 通常我会在不同的文件中创build一个控制器模块,一个服务模块等等,并将它们注入到我在另一个文件中find的主应用程序模块中。 例如:
// My Controllers File angular.module('my-controllers',[]) .controller('oneCtrl',[...]) .controller('twoCtrl',[...]); // My Services File angular.module('my-services',[]) .factory('oneSrc',[...]) .facotry('twoSrc',[...]); // My Directives File angular.module('my-directives',[]) .directive('oneDrct',[...]) .directive('twoDrct',[...]); // My Main Application File angular.module('my-app',['my-controllers','my-services','my-directives',...]);
但随着项目的发展,这些文件中的每一个都越来越大。 所以我决定把它们分成基于每个控制器或服务的单独的文件。 我发现使用angular.module('mod-name').
没有注入arrays,这是你需要这个工作。 在一个文件中声明一个全局variables,并期望在另一个文件中容易获得这个variables只是不起作用,或者可能会有意想不到的结果。
所以总之我的应用程序看起来像这样:
// Main Controller File angular.module('my-controllers',[]); // Controller One File angular.module('my-controllers').controller('oneCtrl',[...]); //Controller Two File angular.module('my-controllers').controller('twoCtrl',[...]);
我也这样做了服务文件,不需要改变主应用程序模块文件,你仍然注入相同的模块。
另一种做法是将控制器,指令等填充到自己的模块中,并将这些模块注入到“主”模块中:
angular.module('app.controllers', []) .controller('controller1', ['$scope', function (scope) { scope.name = "USER!"; }]); angular.module('app.directives', []) .directive('myDirective', [function () { return { restrict: 'A', template: '<div>my directive!</div>' } }]); angular.module('app', [ 'app.controllers', 'app.directives' ]);
全球范围内没有任何东西。
我喜欢分割我的文件和我的模块。
像这样的东西:
app.js
var myApp = angular.module('myApp', ['myApp.controllers', 'myApp.directives', 'myApp.services']); myApp.config(['$routeProvider', function($routeProvider) { /* routes configs */ $routeProvider.when(/*...*/); }]);
directives.js
var myDirectives = angular.module('myApp.directives', []); myDirectives.directive( /* ... */ );
service.js
var myServices = angular.module('myApp.services', []); myServices.factory( /* ... */ );
我不是“链式风格”的忠实粉丝,所以我宁愿总是写下自己的变数。
对我来说,链接是最紧凑的方式:
angular.module("mod1",["mod1.submod1"]) .value("myValues", { ... }) .factory("myFactory", function(myValues){ ... }) .controller("MainCtrl", function($scope){ // when using "Ctrl as" syntax var MC = this; MC.data = ...; }) ;
这样我可以轻松地在模块之间移动组件,永远不需要声明相同的模块两次,也不需要任何全局variables。
如果文件太长,解决方法很简单 – 分成两个文件,每个文件在顶部声明自己的模块。 为了获得更多的透明度,我尝试为每个文件保留一个独特的模块,并将其命名为类似文件的完整path。 这样,我也不需要编写没有[]
的模块,这是一个常见的难题。
我build议遵循Angularjs风格指南 。
他们处理命名约定的所有概念,模块化您的应用程序等等。
对于angular度2,您可以检查Angular 2样式指南