大型AngularJS应用程序设计

时间:2014-09-16 17:17:39

标签: javascript angularjs

我需要建议设计一个具有多个复杂模块的AngularJS应用程序,并根据验证后加载模块的用户角色。授权。有些用户可以访问一个简单的模块,有些用户可以访问仪表板,有些用户可以访问2个以上的模块。

我们已经确定了很多可以在不同模块中重复使用的指令。在设计阶段,我们已经确定了应该存在的以下事项,我们对以下某些项目有答案,但我们仍然需要专家的建议:

  • 一个模块可以有
    • 局部模板
    • 控制器
    • 指令
    • 服务
  • 异常处理(HTTP状态代码或业务错误)
  • 记录(使用行号,从哪个功能)
  • 可能还需要在服务器中保存记录的信息
  • 应该能够打开和关闭日志记录
  • 通过工厂类的自定义小部件(在其他模块中重复使用)
  • 共享指令(独立范围)
  • 共享模块
  • 共享实用程序(排序,过滤等)
  • 根据主数据的枚举器
  • 通过单身人士的常数
  • 身份验证(CSRF)
  • 离线存储
  • REST服务
  • 从一个模块调度并在其他模块中处理的事件处理

应用程序的UI看起来像是一个固定的菜单栏,页面顶部有一个下拉导航,左上角有多个链接,具体取决于用户的角色。当用户单击链接时,相应的模块应该加载到页面中。必须有一个空的项目,它是手动引导的,并在运行时加载其他模块。

我们的方法是拥有以下文件夹结构:

  • 应用
    • 资产
      • CSS
      • lib js
      • 图像
    • 常见组件
      • 指令
      • 应用
      • 验证
      • 用于保存$ resource调用的服务代理
      • 枚举
      • 常量
    • 模型
      • entity json(示例客户,产品等)
    • 业务模块A.
      • 局部模板
      • 指令
      • 服务
      • 控制器
    • 业务模块B
    • 业务模块C
    • 的index.html
    • 需要配置文件

所以我的问题是:

  • 模块内的服务如何与其他模块通信?
  • 模块应该独立开发和运行吗?
  • 如何通过传输数据来处理模块之间的通信?
  • 如何整合上述所有元素,特别是异常处理,日志记录?
  • 开发人员应该了解我们定义的约定?
  • 调用日志记录,在模块之间发送信息的方法是什么?

3 个答案:

答案 0 :(得分:15)

我建议将yeoman包含在您的工作流程中,并为项目使用生成器,这样可以更轻松地构建应用程序,特别是如果您在团队中工作。

今年早些时候,来自angular的人发布了document,其中包含针对您的应用结构的最佳做法,我建议您阅读它,据说那里有基于这些最佳做法的生成器我完全推荐cg-angular

我引用cg-angular网站:

  

所有子生成器都会提示用户指定保存新内容的位置   文件。因此,您可以创建所需的任何目录结构,   包括筑巢。生成器将创建一些文件   项目的根目录,包括index.html,app.js和app.less。您   确定如何构建项目的其余部分。

关于您的问题:

  • 模块内的服务如何与其他模块通信?
  

您可以为指令/和服务/创建一个文件夹   在不同的模块中重用。

  • 模块应该独立开发和运行?
  

你可以在app中拥有多个模块(你可以将它们加载为   需要,也许使用require js但这是offtopic)

  • 如何通过传输数据来处理模块之间的通信?
  

使用服务在不同的控制器之间传递信息   模块

  • 如何整合上述所有元素,特别是异常处理,日志记录?
  

你可以做一般的错误处理程序和通用的http拦截器   所有模块

  • 开发人员应该了解我们定义的约定?
  

使用他们被认可的发电机,他们给出订单和   团队需要的约定。

答案 1 :(得分:9)

有很多好问题要问;它们似乎分为两大类 - 第一类是代码结构问题,第二类是指标(日志等)。

  

模块内的服务如何与其他模块通信?

理想情况下,您应该使用模块的指令。这样,您可以利用通过require属性链接控制器的功能。 Here is a page on sharing data between directives and controllers

  

模块应该独立开发和运行吗?

我假设您在考虑单元测试。是的,理想情况下,您的模块应尽可能紧凑,以便于测试。

  

如何通过传输数据来处理模块之间的通信?

这是通常使用services的地方。注意:服务,工厂和提供者在AngularJS中都是一样的,它们只是以稍微不同的方式声明。选择一个你最舒服的人。

  

如何集成以上所有元素,特别是异常处理,日志记录?

记录是一个单独的问题。 AngularJS的优点在于,您可以非常轻松地扩充框架的现有部分,以便根据需要添加功能或行为。您可以使用decorators执行此操作。 Here is an example of exception logging that I think will cover any use cases you might be interested in

  

开发人员应该了解我们定义的约定吗?

答案总是一样的:沟通就是他们所知道的。开发人员需要将惯例社交化,否则你永远不会得到买入。

  

要记录什么方法,在模块之间发送信息?

上面回答。

答案 2 :(得分:7)

  

大型AngularJS和JavaScript应用程序中的代码组织

     

许多开发人员都在努力解决如何组织应用程序的代码问题   基地一旦大小增长。我最近在AngularJS和   JavaScript应用程序,但从历史上看,这是一个问题   所有技术,包括我曾参与过的许多Java和Flex应用程序   过去。

     

总体趋势是对按类型组织事物的迷恋。它   与人们组织他们的方式有着惊人的相似之处   服装。

     

在地板上堆积

     

让我们来看看角种子,这是官方的起点   AngularJS应用程序。 " app"目录包含以下结构:

     

css / img / js / app.js controllers.js directives.js filters.js   services.js lib / partials / JavaScript目录有一个文件   我们写的每种类型的对象。这就像组织你的   衣服在地板上成不同的堆。你有一堆袜子,   内衣,衬衫,裤子等你知道你的黑色羊毛袜子   那堆在角落里,但它需要一段时间来挖掘它们   进行。

     

这是一团糟。人们不应该像这样和开发者一样生活   不应该像这样编码。一旦你超过六打左右   控制器或服务这些文件变得笨拙:你反对的对象   寻找很难找到,源控制中的文件更改集成为   不透明等。

     

袜子抽屉

     

组织JavaScript的下一个逻辑过程涉及创建一个   一些原型的目录和将对象分成它们的   自己的文件。为了继续服装比喻,我们现在投资了一个   漂亮的mohaghony梳妆台,并计划将袜子放在一个抽屉里,内衣   在另一个地方,整齐地折叠我们的裤子和衬衫。

     

让我们想象一下,我们正在建立一个带登录的简单电子商务网站   流程,产品目录和购物车UI。我们还定义了新的   模型的原型(业务逻辑和状态)和服务(代理   到HTTP / JSON端点)而不是将它们集中到Angular的单个   "服务"原型。我们的JavaScript目录现在看起来像这样:

     

controllers / LoginController.js RegistrationController.js   ProductDetailController.js SearchResultsController.js directives.js   filters.js models / CartModel.js ProductModel.js SearchResultsModel.js   UserModel.js services / CartService.js UserService.js ProductService.js   太好了!现在可以通过浏览文件树或轻松找到对象   使用IDE快捷方式,源控件中的更改集现在可以清楚地指出   什么被修改,等等。这是一个重大改进,但仍然受到影响   从某些限制。

     

想象一下你在办公室,发现你需要一些服装   明天早上商务旅行干洗。你打电话给家里   请你的重要人士带上你的黑炭和蓝色   细条纹适合清洁工。并且不要忘记带衬衫的灰色衬衫   黑色佩斯利领带和白色衬衫搭配纯黄色领带。   想象一下,你的重要人物完全不熟悉   你的梳妆台和衣柜。当他们筛过领带抽屉时,他们   看到三个黄色领带。哪一个选择?

     如果你的服装是由服装组织的,那会不会很好?而   有成本和空间等实际限制因素   在现实世界中服装很难,类似的东西也可以   以零成本完成代码。

     

模块化

     

希望这些陈腐的隐喻并不是太乏味但是这里有   回顾一下:

     

您的重要人物是团队中的新开发人员   要求修复应用中众多屏幕之一的错误。该   开发人员筛选目录结构并查看所有内容   整齐有序的控制器,模型和服务。不幸的是   告诉他/她没有关于哪些物体相关或有   相互依赖。如果在某些时候开发人员想要   重用一些代码,他们需要从一堆代码中收集文件   不同的文件夹,将永远忘记另一个文件夹中的代码   别的地方。信不信由你,你很少需要重用所有   来自新报告应用程序中的电子商务应用程序的控制器   你正在建设。但是,您可能需要重用一些   认证逻辑。如果这一切都在一个,那就不好了   地点?让我们根据功能区域重新组织应用程序:

     

cart / CartModel.js CartService.js common / directives.js filters.js   product / search / SearchResultsController.js SearchResultsModel.js   ProductDetailController.js ProductModel.js ProductService.js user /   LoginController.js RegistrationController.js UserModel.js   UserService.js任何随机开发人员现在都可以打开顶级文件夹   并立即深入了解应用程序的功能。对象   在同一个文件夹中有一个关系,有些会有依赖关系   在别人身上。了解登录和注册过程的工作原理   就像浏览该文件夹中的文件一样简单。通过原始重用   复制/粘贴至少可以通过将文件夹复制到其中来完成   另一个项目。

     

使用AngularJS,我们可以更进一步,创建一个模块   这个相关的代码:

     

1 2 3 4 5 6 7 8 9 10 11 12 13 var userModule =   angular.module(' userModule',[]); userModule.factory(' userService&#39 ;,   [' $ http',功能($ http){返回新的UserService($ http); }]);
  userModule.factory(' userModel',[' userService',function(userService)   {return new UserModel(userService); }]);
  userModule.controller(' loginController',[' $ scope',' userModel',   的LoginController]); userModule.controller('这个RegistrationController&#39 ;,   [' $ scope',' userModel',RegistrationController]);视图   由GitHub用❤托管的rawUserModule.js如果我们然后放置   UserModule.js进入用户文件夹,它变成了一个" manifest"的   该模块中使用的对象。这也是一个合理的地方   为RequireJS或Browserify添加一些加载器指令。

     

通用代码提示

     

每个应用程序都有许多模块使用的公共代码。我们   只需要一个位置,它可以是一个名为" common"要么   "共享"或者你喜欢什么。在很大的应用程序中往往会有   在功能和跨领域问题上有很多重叠。   这可以通过几种技术来管理:

     

如果您的模块对象需要直接访问多个" common"   对象,为它们写一个或多个Facades。这可以帮助减少   由于太多,每个对象的协作者数量   合作者通常是代码气味。如果你的常见"模   变得很大,将其细分为解决特定问题的子模块   功能区或关注点。确保您的应用程序模块仅使用   "普通"他们需要的模块。这是"接口的变体   隔离原则"来自SOLID。在$ rootScope上添加实用程序方法   因此它们可以被子范围使用。这可以帮助防止不得不这样做   将相同的依赖关系(例如" PermissionsModel")连接到每个   应用程序中的控制器。请注意,这应该谨慎地完成   避免混淆全局范围并产生依赖关系   非显而易见的。使用事件来分离两个不需要的组件   明确地引用彼此。 AngularJS使这成为可能   通过Scope对象上的$ emit,$ broadcast和$ on方法。一个   控制器可以触发事件来执行某些操作,然后接收一个   通知行动已完成。关于资产和测试的快速说明

     

我认为在组织方面有更大的灵活空间   HTML,CSS和图像。将它们放入"资产"的子文件夹   模块可能在封装之间达到最佳平衡   模块的资产依赖性并没有太多混乱。   不过我觉得这个内容有一个单独的顶级文件夹   包含一个镜像应用程序包结构的文件夹结构   也是合理的。我认为它也适用于测试。

请查看以下链接,

<强> https://blog.safaribooksonline.com/2014/03/27/13-step-guide-angularjs-modularization/