如何思考angularjs中的控制器

时间:2013-08-02 20:57:16

标签: model-view-controller angularjs controller

我正在与Angularjs擦肩而过,并且认为我会在SO的优秀人群中提出一个概念性的问题。这是来自经验丰富的开发人员的新手问题。

该应用程序具有仪表板要求......单个页面可以显示应用程序的许多部分。不同的用户类型获得不同的仪表板。我们已经有了传统的后端,因此首要任务是构建仪表板,以显示其新RESTful服务层中的许多位。

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

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

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

我正在寻找基于实际经验和/或对我尚未找到的优秀链接的参考的切实建议。

3 个答案:

答案 0 :(得分:7)

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

控制器的角色

  1. 初始化(加载初始数据,设置选项)
  2. 通过$ scope
  3. 向模板公开变量和函数
  4. 应用程序流程(通过暴露可以改变状态的函数,或$watch es)
  5. 我发现,与传统的MVC框架非常相似,Angular应用程序中的控制器应该非常超薄。 控制器中应该有很少的业务逻辑,而应该将其封装在模型中。在听到MiškoHevery的演讲后的以下内容后,我得出了这个结论:the purpose of the scope is to refer to the model and not be the model。”这是我从演讲中得到的最有价值和最有启发性的一句话(虽然我建议观看整个视频);这条线直接导致我减少了近50%-70%的控制器。

    例如,我的公司有一个Order的概念。我创建了一个模型,它封装了这个业务对象的所有属性,以及它的行为,并将它们注入到控制器中。我们拥有的一项业务规则是能够向Booking添加Order(另一个业务对象)。最初在我的控制器中,我有一个$scope.addBooking函数,它首先创建了一个新的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行为),那么这表明控制器的某些部分可以被拉出指令,使你的控制器变得更加苗条。

答案 1 :(得分:4)

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

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

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

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

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

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

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

使用控制器的建议和重新评估

保持小。

避免在其中使用DOM操作(改为使用指令)。

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

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

我希望这可以帮到你。

答案 2 :(得分:3)

基本理念

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

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

如果您担心此模式的可扩展性,则应将业务逻辑和数据访问权限置于Angular Services as described here之内。这为您提供了大量的业务逻辑操作重用以及单元可测试性。

<强> TLDR;

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

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