8

我正在用 Angularjs 触及表面,并认为我会在 SO 的优秀人员面前提出一个概念性问题。这是来自经验丰富的开发人员的新手问题。

该应用程序具有仪表板要求......一个显示应用程序许多部分的内容的单个页面。不同的用户类型获得不同的仪表板。我们已经有一个遗留后端,所以第一个任务是构建仪表板以显示其新的 RESTful 服务层的许多位。

我想知道我应该如何从概念上考虑支持这一点所需的控制器?

第一个问题是……它们应该以模型为中心还是以视图为中心?换句话说,它们应该是“以视图为中心”的控制器,其中包含“仪表板”这个词吗?或者他们应该更关注他们所代表的模型元素,比如“任务”、“联系人”、“通知”。还是应该同时存在仪表板控制器与以模型为中心的控制器一起使用的地方?

下一个问题是……控制器应该代表什么级别的粒度?如果以视图为中心的“仪表板”控制器,它们应该是“ManagerDashboardController”和“WorkerDashboardController”吗?如果以模型为中心的控制器,是否应该有诸如“LateTasks”和“OnTimeTasks”之类的控制器,因为我需要在仪表板的不同部分显示它们,数据略有不同?

我正在寻找基于现实世界经验和/或我尚未找到的重要链接的参考的切实建议。

4

3 回答 3

7

以下是我过去 6 个月在 Angular 中开发业务应用程序的看法:

控制器的角色

  1. 初始化(加载初始数据、设置选项)
  2. 通过 $scope 向模板公开变量和函数
  3. 应用程序流程(通过暴露可以改变状态的函数,或$watches)

我发现,就像在传统的 MVC 框架中一样,Angular 应用程序中的控制器应该非常纤薄。几乎没有任何业务逻辑应该在控制器中,而是应该封装在您的模型中。在听了 Miško Hevery 的演讲后,我得出了这个结论:范围的目的是参考模型而不是模型。” 这是我从那个演示中得到的最有价值和最有启发性的一句话(尽管我建议观看整个视频);这条线直接导致我将我的控制器缩小了近 50%-70%。

例如,我的公司有一个Order. 我创建了一个模型,该模型封装了该业务对象的所有属性及其行为,并将它们注入到控制器中。我们拥有的一个业务规则是能够将Booking(另一个业务对象)添加到Order. 最初在我的控制器中,我有一个$scope.addBooking函数,它首先创建一个 new Booking,然后接受订单并执行一个$scope.order.bookings.push(newBooking). 相反,我将这个业务逻辑(addBooking函数)直接移动到我的Order模型中,然后在模板中我可以执行类似的操作,<button ng-click="order.addBooking()">Add Booking</button>而无需在控制器中添加一行代码。

当我第一次开始使用 angular 时,我在控制器中放入的很多代码,我发现可以被剥离并放置在我的模型、指令或服务中(在我的例子中主要是前两个)。留在我的控制器中的其余代码几乎都属于我上面列出的上述 3 个角色之一。它要么是初始化代码(例如,触发 AJAX 请求以获取相关业务对象的数据)、对象的范围分配,要么是处理应用程序流的函数的范围分配(例如,$scope.save或者$scope.cancel可能会将您送回不同的页面)。

控制器应该以模型为中心还是以视图为中心?

这是一个有趣的问题,我以前没有考虑过。当我听到以视图为中心时,我会想到一个控制器,它主要处理视图以及事物的显示方式。我觉得不应该有任何纯粹以视图为中心的控制器,原因是看起来以视图为中心的控制器可能可以转换为指令。您提到以视图为中心的控制器就像一个Dashboard控制器,这听起来像是绝对可以制成通用指令的东西。你的指令应该封装你的大部分视图逻辑,而你的控制器专注于简单地将你的模型暴露给视图以供使用(回到控制器的角色)。这让我认为控制器应该更频繁地以模型为中心。

我认为我能得出的唯一结论是,如果控制器开始变得过于以视图为中心(有许多主要处理视图和 UI 行为的变量和函数),那么这表明控制器的某些部分可以被拉出成一个指令,使你的控制器更苗条。

于 2013-08-03T08:44:40.123 回答
4

这是非常主观的,但这是我对您的问题的回答

控制器应该以模型为中心还是以视图为中心?

这取决于(一如既往),我总是尝试为页面的不同部分设置小型控制器。

页面的某些部分非常以视图为中心(通常是在不同视图之间共享的部分)。我通常有一个menuCtrl、一个headerCtrl 和footerCtrl。此 ctrl 与页面的这些部分非常耦合,因此使它们以视图为中心。

视图的其他部分,与业务相关的部分与业务规则和模型的扩展更加耦合,因此我使这些 ctrls 以模型为中心。在一个帐户的业务应用程序上,我可能会有一个 accountCtrl、一个 ownerCtrl 等等。通过这样做,如果需要,我可以在不同的视图上重用它们(并且更容易测试)

控制器应该代表什么级别的粒度?

尽可能最小。尝试使用小型控制器为页面的不同部分准备模型。如果你有一个大控制器,它会很难测试和维护,你可能会被迫在应用程序的不同部分复制代码。

与控制器的建议和建议

保持小。

避免在它们内部进行 DOM 操作(改用指令)。

使用控制器只是为了准备模型。尽可能将应用程序的所有逻辑委托给服务。如果你这样做了,那么你的控制器是以视图为中心还是以模型为中心的并不重要。

正如我之前所说,这是一个非常主观的问题,我相信很多人会不同意我的观点。

我希望这可以帮助你。

于 2013-08-03T00:23:59.963 回答
3

基本理念

所以我实际上正在使用AngularJs将遗留代码库迁移到基于restful的Web服务架构

控制器负责管理视图(即网页)使用的数据。我个人的偏好是控制器和它所服务的视图之间存在一对一的关系。因此,基于这个问题,Angular 控制器应该更加以视图为中心。我敢肯定,有很多人会不同意我的观点。

如果您担心这种模式的可扩展性,您应该将您的业务逻辑和数据访问放在Angular 服务中,如此处所述。这为您提供了大量的业务逻辑操作重用以及单元可测试性。

TLDR;

Angular 的规范一直在变化,每个新版本都会有一个新标准。更以视图为中心的架构看起来适合此应用程序。

有关该主题的更完整阅读,我建议您查看:

于 2013-08-02T21:27:57.667 回答