AngularJS模块声明的最佳实践?

kd3sttzy  于 2022-12-22  发布在  Angular
关注(0)|答案(7)|浏览(116)

我在应用程序中声明了很多Angular模块,最初是使用“chained”语法声明的,如下所示:

angular.module('mymodule', [])
    .controller('myctrl', ['dep1', function(dep1){ ... }])
    .service('myservice', ['dep2', function(dep2){ ... }])
    ... // more here

但是我觉得这并不容易理解,所以我开始使用一个模块变量来声明它们,如下所示:

var mod = angular.module('mymodule', []);

mod.controller('myctrl', ['dep1', function(dep1){ ... }]);

mod.service('myservice', ['dep2', function(dep2){ ... }]);
...

第二种语法对我来说似乎可读性更强,但我唯一的抱怨是这种语法将mod变量排除在全局作用域之外,如果我有其他名为mod的变量,它将被下一个变量覆盖(以及与全局变量相关的其他问题)。
所以我的问题是,这是最好的方法吗?还是这样做会更好?:

(function(){
    var mod = angular.module('mymod', []);
    mod.controller('myctrl', ['dep1', function(dep1){ ... }]);
    mod.service('myservice', ['dep2', function(dep2){ ... }]);
    ...
})();

或者它甚至重要到需要关心吗?只是好奇地想知道模块声明的“最佳实践”是什么。

oogrdqng

oogrdqng1#

    • 声明模块的“最佳”方式**

由于angular在全局作用域中,模块保存在它的变量中,所以可以通过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){
      //..
  }])
})();

不需要其他全局变量。
当然,这完全取决于个人喜好,但我认为这是最好的做法,因为
1.你不必污染全球范围
1.你可以在任何地方访问你的模块,并随意地将它们和它们的函数分类到不同的文件中
1.可以使用“use strict”的函数形式;
1.文件的加载顺序并不重要

模块和文件排序选项

这种声明和访问模块的方式非常灵活,可以通过函数类型(如另一个答案中所述)或路径对模块进行排序,例如:

/******** sorting by route **********/    
angular.module('home')...
angular.module('another-route')...
angular.module('shared')...

最后如何排序取决于个人喜好以及项目的规模和类型。我个人喜欢将模块的所有文件分组到同一个文件夹中(排列在指令、控制器、服务和过滤器的子文件夹中),包括所有不同的测试文件,因为它使模块更可重用。因此,在中等规模的项目中,我最终使用一个基本模块,包括所有基本路由及其控制器、服务、指令和或多或少复杂的子模块,当我认为它们对其他项目也有用时,例如:

/******** 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'
]);

对于非常大的项目,我有时会按路线(如上所述)或某些选定的主要路线(甚至是路线和某些选定组件的组合)对模块进行分组,但这确实取决于具体情况。

**编辑:**只是因为它是相关的,我最近又遇到了:注意一个模块只能创建一次(通过在angular.module-function中添加第二个参数)。这会扰乱应用程序,并且很难检测到。
**2015 EDIT关于模块排序:**经过一年半的Angular 经验,我可以补充说,在应用中使用不同命名的模块的好处是有限的,因为AMD仍然不能很好地与Angular 和服务,指令和过滤器是全球范围内的Angular 上下文无论如何(如这里所示)。仍然有一个语义和结构的好处,虽然它可能是有帮助的,能够包括/排除一个模块与单行代码注解或删除。

通过类型**(例如“myMapSubModule. controllers”)分离子模块也几乎**没有多大意义,因为它们通常相互依赖。

vsnjm48y

vsnjm48y2#

我喜欢Johnpapa的angular-styleguide,下面是一些与此问题相关的规则:

规则:命名函数与匿名函数

避免使用匿名函数:

// dashboard.js
angular
  .module('app')
  .controller('Dashboard', function() { })

请改用命名函数:

// dashboard.js
angular
  .module('app')
  .controller('Dashboard', Dashboard);

function Dashboard() { }

正如作者所说:第一个月

规则:每个文件定义1个组件。

避免在一个文件中包含多个组件:

angular
  .module('app', ['ngRoute'])
  .controller('SomeController', SomeController)
  .factory('someFactory', someFactory);

function SomeController() { }

function someFactory() { }

相反,使用一个文件定义模块:

// 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的注解,上述代码应该 Package 在IIFE中,例如:

(function (window, angular) {
  angular.module('app')
   .controller('Dashboard', function () { });
})(window, window.angular);
bejyjqdl

bejyjqdl3#

我最近也遇到了这个难题。我一开始也像你一样使用链式语法,但是从长远来看,它在大型项目中变得笨拙。通常我会在单独的文件中创建一个控制器模块,一个服务模块等等,然后将它们注入到我在另一个文件中找到的主应用程序模块中。例如:

// 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').而不使用注入数组是您工作所需要的。在一个文件中声明全局变量并期望它在另一个文件中随时可用是行不通的,或者可能会产生意想不到的结果。
简而言之,我的申请看起来像这样:

// 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',[...]);

我对服务文件也做了同样的处理,不需要更改主应用程序模块文件,您仍然可以向其中注入相同的模块。

iszxjhcz

iszxjhcz4#

另一种做法是将控制器、指令等填充到它们自己的模块中,然后将这些模块注入到你的“主”模块中:

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'
]);

全局作用域中没有任何内容。
http://plnkr.co/edit/EtzzPRyxWT1MkhK7KcLo?p=preview

omhiaaxx

omhiaaxx5#

我喜欢把我的文件和模块分开。
大概是这样的
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( /* ... */ );

我不是"链式风格"的忠实粉丝,所以我更喜欢总是写下我的变量。

ars1skjm

ars1skjm6#

我建议您遵循Angularjs Style Guide
他们处理所有的概念,从命名约定,以模块化您的应用程序等。
对于Angular 2,可以选中Angular 2 Style Guide

a5g8bdjr

a5g8bdjr7#

对我来说,链接是最紧凑的方式:

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 = ...;
 })
 ;

这样我就可以很容易地在模块之间移动组件,不需要两次声明同一个模块,也不需要任何全局变量。
如果文件太长,解决方案很简单--拆分为两个文件,每个文件在顶部声明自己的模块。为了更透明,我尝试每个文件保留一个唯一的模块,并将其命名为类似文件的完整路径。这样我也永远不需要编写没有[]的模块,这是一个常见的痛点。

相关问题