【问题标题】:When to use nested controllers instead of services in angularjs?何时在 angularjs 中使用嵌套控制器而不是服务?
【发布时间】:2013-07-21 13:42:50
【问题描述】:

我刚开始使用 AngularJS,所以我不是专家。

我有一个 div 代表我的 html 视图的正确区域。在那个 div 我有一个控制器,即

<div class="rightContainer" ng-controller="rightContainerCtrl">...</div>

在那个 div 里面我有一个表格、一个搜索区域等。那个 div 里面的每个区域都有自己的控制器,它看起来像这样:

<div class="rightContainer" ng-controller="rightContainerCtrl">
...
   <div class="search" ng-controller="searchCtrl">...</div>
...
   <div class="table" ng-controller="tableCtrl">...</div>

 </div>

例如,搜索区域有自己的控制器,它是 rightContainerCtrl 的子级,因为它需要更改父级 (rightContainerCtrl) 中的一些内容,但 rightContainer div 正在增长,现在它很大,并且包含多个嵌套控制器。

我认为在这种情况下使用这种嵌套控制器是不好的,因为所有嵌套控制器共享父范围,并不是所有控制器都需要访问所有父范围变量,所有控制器也是 rightContainerCtrl 的“囚徒”,因此它们与父控制器高度耦合。

它看起来像一个God object 反模式(在这种情况下是上帝控制器),所以我认为我可以重构我的代码以消除 rightContainerCtrl 控制器并改用服务(就像在 @ 987654322@),然后控制器将使用该服务,而不是共享范围变量。

但由于我不是 AngularJs 专家,我不确定我是否正确,或者离开这个父控制器是否更好,也许我遗漏了一些东西,所以我的问题是

什么时候使用嵌套控制器(嵌套范围)更好,什么时候在 angularjs 中使用服务更好?

【问题讨论】:

    标签: angularjs anti-patterns god-object


    【解决方案1】:

    控制器/范围层次结构不应规定数据/模型在应用程序中的共享方式。当您想到 Angular 中的数据共享时,请考虑依赖注入。

    在@shaunhusain 的回答中引用的视频中,Misko 指出范围应该引用模型,而不是模型 - 所以不要建模/将您的数据放入范围。您的模型/数据通常应该在服务中。

    在编写 Angular 应用程序时,首先要考虑您的模型。将它们放入services with APIs 以获取/编辑/操作模型。然后设计你的观点。每个视图都应该投影/使用/操作模型的某些子集。为每个视图定义一个控制器,将所需的模型子集简单地粘合到视图上。让你的控制器尽可能的薄。

    (也不建议将控制器命名为rightContainerCtrl。控制器不应该知道演示/布局。)

    【讨论】:

    • 感谢您的回答,实际上控制器不应该知道表示,所以从这个意义上说,仅仅因为视图需要一个 div 层次结构,并不意味着控制器需要嵌套,因为它们应该与视图分离/独立。
    • 另外,如果你有一个控制器和一组子控制器,可能是你使用父控制器作用域作为模型,这是一种不好的做法,在这种情况下需要服务,而不是父控制器。
    【解决方案2】:

    这是 100% 的判断,应该基于几点。

    使用事件会创建极其松散耦合的组件,它们实际上不需要相互了解,如果您遇到某些父控制器会减轻一堆控制器(通过服务)之间通信的需要的情况,那么它是可能是更好的解决方案。

    但是,如果您对每个依赖于服务的控制器都满意(这不是真正的问题),那么您可以使用该服务作为在控制器之间传达更改的一种方式。我已经看到了大量反对单例的论点(其中服务是一种风格,注入的单例,但仍然是单例)我发现这些论点大多没有实际意义,并且通常缺乏真正优雅和简洁的解决方案。如果争论不断地讨论当你从 A 到 D 时你不想走 B 路,但他们似乎从来没有提供 C 路,我真的不明白这一点。

    http://www.youtube.com/watch?v=ZhfUv0spHCY&t=30m34s

    我在视频中找不到确切的点,但在最后的某个地方,他讨论了控制器与服务的使用(他还回顾了双向数据绑定,这将阻止您需要污染全局范围,所以说话)。

    【讨论】:

    • 感谢分享该视频,我观看了它,现在我对 AngularJs 有了更好的了解。 Mark Rajcok 在他们的回答中暴露了一个很好的观点,并且视频也解释了它。您应该为您的模型使用服务,并且您的模型需要与控制器和范围解耦,因此在我的示例中,rightContainerCtrl 是模型,因为多个嵌套控制器正在使用该范围内的变量,但这是一种不好的做法,它应该是一项服务。
    • @MiguelA.Carrasco 是的,很高兴你也从视频中得到了一些东西,我最近在这里推荐了很多,因为它似乎涵盖了很多常见的失误。我也 +1 了马克的回答,他解释得很好,还有很多其他非常好的答案。
    • 编写事件以在控制器之间进行通信绝对是一种痛苦。我宁愿为此使用嵌套范围。或服务。
    猜你喜欢
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 2013-09-27
    • 2017-10-11
    • 1970-01-01
    • 2018-09-29
    • 1970-01-01
    相关资源
    最近更新 更多