我需要建议设计一个具有多个复杂模块的AngularJS应用程序,并根据验证后加载模块的用户角色。授权。有些用户可以访问一个简单的模块,有些用户可以访问仪表板,有些用户可以访问2个以上的模块。
我们已经确定了很多可以在不同模块中重复使用的指令。在设计阶段,我们已经确定了应该存在的以下事项,我们对以下某些项目有答案,但我们仍然需要专家的建议:
应用程序的UI看起来像是一个固定的菜单栏,页面顶部有一个下拉导航,左上角有多个链接,具体取决于用户的角色。当用户单击链接时,相应的模块应该加载到页面中。必须有一个空的项目,它是手动引导的,并在运行时加载其他模块。
我们的方法是拥有以下文件夹结构:
所以我的问题是:
答案 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/ 强>