1

我们有一个相当大的 angularJS 应用程序,所有控制器都在一个文件中。

我们正在考虑将每个控制器拆分为相应的文件。有什么理由不这样做吗?

我们想要拆分它的原因是因为更容易管理文件中的源代码控制/更改,而且显然更直观。

请指教。

4

3 回答 3

4

在我看来,构建大型AngularJS 应用程序的最佳方式是按照 Peter Bacon Darwin 和 Pawel Kozlowski 在他们的“使用 AngularJS 进行 Web 应用程序开发”一书中提出的功能来完成。

而不是 AngularJS 种子项目(以及许多其他项目,如 Yeoman 的 generator-angular)推荐的“技术驱动”的结构意味着每个元素类型(如控制器、部分/视图等)都位于其自己的文件夹中,您应该使用“领域驱动”结构,它反映了您代码中的业务领域

它有很多优点,例如:

  • 使代码的所有权明确而清晰,
  • 引入了所有模块共享的通用语言,
  • 授权(在某种程度上)与业务分析师直接沟通,
  • 由于对合并等的需求较低,因此消除了潜在的冲突。

这是上面提到的书中提出的结构的示例(只是为了澄清想法):

项目中的顶级目录:

- src: contains application source code
- test: contains accompanying automated tests
- vendor: contains third party dependencies
- build: contains build scripts
- dist: contains build results, ready to be deployed in a target environment

src文件夹内(固定):

- app: AngularJS-specific code, domain-driven
- common: AngularJS-specific code, boiler-plate
- assets: holds images and icons,
- less: LESS variables
- index.html - entry point to the application

应用程序文件夹内(域驱动),例如网上商店:

- shop
  - products
  - customers
  - orders
    - orderlists
    - orderdetails
    - ... etc.
- admin
  - users
  - ... etc.

每个文件夹都包含所有相关代码,包括部分、脚本等。

于 2013-10-14T16:48:12.577 回答
2

来自Brian Ford 的一篇文章

大型应用程序最大的问题可能是把所有代码放在哪里。在组织工具的工具带上,您拥有文件、目录、模块、服务和控制器。要快速了解良好的 AngularJS 项目结构,请查看 Github 上的 Angular Seed。但是,我想更深入一点,并就项目结构提供一些额外的建议。让我们从目录开始,沿着列表往下走。

例如,您的文件结构可以是这样的:

project/
       app.js
       controllers/ #your controllers files here
       views/  #your templates here
       services/  #your services files
       directives/ #your custom directives

每个文件都应该有一个“事物”,其中“事物”是控制器、指令、过滤器或服务。这使得小而集中的文件。它还有助于为 API 的运行情况创建一个试金石。如果您发现自己过于频繁地来回翻阅文件,这表明您的 API 过于复杂。你应该重新思考、重构和简化。

查看文章了解更多详情。

于 2013-05-20T16:43:13.377 回答
1

有很多不同的方式可以构建你的应用程序,几乎没有对错之分。所以不,没有理由不这样做,看起来它是有道理的。

我个人根据我的经验决定使用以下结构给你一个例子:

我使用 Angular Seed 项目的目录结构:

  • app/js -> 包含所有动态 js 脚本
  • app/lib/angular114 -> 包含当前的 angularjs 版本(我可以使用多个版本进行测试)
  • app/lib/mycompany -> 包含我保存在单独存储库中的所有公司/个人可重用库
  • app/partials -> 包含我根据 app/js 中的 js 文件结构划分到子目录的所有 html 部分。如果我有一个 user.js,那么我就有一个用户目录。

自己的库

在我自己位于 lib/mycompany 的库中,我为所有文件和方法名称加上我的公司前缀。如果我的公司将被称为东亚有限公司,那么我将创建一个名为“ea”的两个字母前缀。这将防止名称与我的动态 js 脚本发生冲突,因为控制器和服务的名称可以通过我的应用程序公开获得。

lib/ea/ea-validators.js

(function() {
  'use strict'
  angular.module('eaValidators', [])
    .directive('eaValidateUnique', [function() {
      // directive code goes here
    }])
    .directive('eaValidateId', [function() {
      // code goes here
    }])
    .controller('MyCtrlJustAsExample', ['$scope', function($scope) {
      // code goes here
    }]);    
})();

我将所有内容分组到逻辑模块中,例如:

  • 验证模块
  • 全局错误处理模块
  • 认证/授权模块
  • ...

例如,身份验证模块包含指令、控制器、服务等。我区分逻辑实体,而不是区分控制器、指令等。我发现这种结构更有效,因为当我想更改例如与验证相关的内容时,我知道它在我的验证模块中。

你可以在这里找到例子:http: //chstrongjavablog.blogspot.ch/

动态内容

我对我的动态 js 文件有类似的方法。例如,如果我想要显示一个用户页面和一个供应商页面,那么我会在我的 js 目录中创建以下文件:

  • 用户.js
  • 供应商.js

同样,这些文件可以在同一文件中包含指令、控制器、服务,这些文件分组在一个模块下。因此,如果我需要更改与用户相关的内容,我会立即知道我会在 user.js 中找到代码。

示例 user.js 可能如下所示:

js/user.js

angular.module('user', ['ngResource'])
  .controller('UserListCtrl', ['$scope', 'User', function($scope, User) {
     // code goes here
  }])
  .controller('UserNewCtrl', ['$scope', 'User', function($scope, User) {
    // code goes here
  }])
 .factory('User', ['$resource', function($resource) {
    return $resource('/api/user/:userId', {userId: '@id'});
 }]);       

把它们粘在一起

js/app.js

然后我使用 js/app.js 将所有内容粘合在一起并进行路由:

angular.module('myApp', ['eaValidators', 'vendor', 'user'])
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/user', {templateUrl: 'partials/user/user-list.html', controller: 'UserListCtrl'});
    $routeProvider.when('/user/new', {templateUrl: 'partials/user/user-new.html', controller: 'UserNewCtrl'});
    $routeProvider.otherwise({redirectTo: '/user'});
}])
  .config(['$httpProvider', function ($httpProvider) {
    $httpProvider.defaults.headers.common['Content-Type'] = 'application/json';
    $httpProvider.defaults.headers.common['Accept'] = 'application/json';
}]);

然后我只是挂钩主 index.html 文件中的文件:

索引.html

<!doctype html>
<html lang="en" ng-app="myApp">
<head>
  <meta charset="utf-8">
  <title>YourApp</title>
  <link rel="stylesheet" href="css/app.css"/>
  <link rel="stylesheet" href="css/style.css"/>
  <link rel="stylesheet" href="css/ea-validators.css"/>
</head>
<body>

  <!-- Display partial pages -->
  <div ng-view></div>

  <!-- Include all the js files. In production use min.js should be used -->
  <script src="lib/jquery203/jquery-2.0.3.js"></script>
  <script src="lib/angular114/angular.js"></script>
  <script src="lib/angular114/angular-resource.js"></script>
  <script src="lib/ea/ea-validators.js"></script>
  <script src="js/app.js"></script>
  <script src="js/user.js"></script>
  <script src="js/vendor.js"></script>
</body>
</html>

这种结构的好处是我可以将例如 user.js 和用户部分复制到另一个项目中并重用大部分代码。

我也有我的全局验证处理程序、错误处理程序、身份验证处理程序,我可以从我的存储库中签出到 lib 目录。

我发现这种结构是迄今为止最有效的。

另一种方法

你也可以使用对你的结构有很大帮助的 YeoMan。然而,它确实添加了很多依赖项,当我尝试使用它时,我在安装过程中遇到了一些依赖冲突的问题。我个人的经验法则是,如果我不能在 1 天内完成某项工作,我会把手从它身上移开,因为我会浪费时间花在代码上。我给自己设定的另一条经验法则是,如果有一个由具有不同目标的个人开发的依赖项拼凑在一起的框架,我会尽可能避免它。请注意,这些是我自己制定的个人规则,可能不适合其他人。出于这些原因,我决定不使用它。但似乎已经有一个相当大的社区。

生产

出于生产目的,您可以使用 UglyfyJS 或 Google Closure Compiler 创建一个压缩的 js 文件,其中包含所有代码或单独压缩的每个文件。

我希望这个描述对你有用。

于 2013-09-28T09:55:59.473 回答