【问题标题】:Preferred way of declaring Controllers声明控制器的首选方式
【发布时间】:2014-05-28 11:12:49
【问题描述】:

AngularJs 中defining a controller 的可用方式很少。具体来说:

  1. “附加到$scope”语法
  2. “控制器为”语法
  3. controller()函数

以上代码展示:

// 1)
ng-controller="MyControllerFn"

// 2)
ng-controller="MyControllerFn as myCtrl"

// 3)
myModule.controller("myCtrl", MyControllerFn);
// or
myApp.controller("myCtrl", ["$scope", function($scope) {

}]);

当然,每一个都有它的优点和缺点。目前我正在使用选项1)。我的问题是,我不知道从长远来看我是否没有遗漏任何东西,现在我可以使用新的“控制器作为”语法。我们的项目非常大,我看不到自己在一年左右的时间内将所有内容都重写为新语法,因为旧语法已被弃用。我宁愿现在慢慢过渡,从今天开始以“好的方式”编写新代码。

一些优点和缺点:

1)

  • (好)与 3) 相比样板更少,因为控制器的自动发现会在遇到 ng-controller 指令时为您处理声明
  • (坏)支持正确的 DI:MyControllerFn.$inject = [...]
  • (不好)难以在控制器的继承树中导航

2)

  • (好)控制器别名清楚地表明了哪些范围变量引用了
  • (好)更清晰的控制器语法,因为将变量分配给this
  • (好)似乎正在改进工具支持 (IDE)
  • (坏)向范围添加太多东西容易出错,例如:`this.arr = ...; // 100 万个项目的数组'

3)

  • (中性)缩小正确(嗯,这可以通过$inject 属性完成)
  • (不好)更冗长的语法,可以通过自动发现完全避免

好的,我错过了什么吗?也许我没有看到明显的东西,因为我最近才迁移到 1.2?


= 编辑

为了清楚起见,绑定和声明控制器是有区别的。前两个演示的选项是关于将控制器绑定到 DOM,而第三个是关于在 Angular 模块中显式声明它。对后者的反对是允许 Angular 通过 DOM 并自动发现控制器,这是我喜欢的做事方式。

【问题讨论】:

    标签: javascript angularjs angularjs-controller


    【解决方案1】:

    直截了当:

    首先,有两件不同的事情需要完成:

    1. 定义控制器的实现(即将“newed”创建控制器实例的函数)。
    2. 将控制器绑定到 DOM 元素(即说“视图的这一部分由称为 'someCtrl' 的控制器实例控制”)。

    那么 Angular 的工作就是将事物联系在一起:

    1. 我在视图中看到元素。
    2. 我看到元素 x 绑定到控制器 y。
    3. 我找到注册为名为 y 的控制器的实现的函数。
    4. 我使用该函数创建了一个新的控制器实例。
    5. 我将新的控制器实例传递给元素(即针对该控制器实例评估在元素及其后代中找到的每个 Angular 表达式 - 除非视图的子树绑定到另一个控制器实例等)。

    (1) 和 (2) 是将控制器绑定到 DOM 元素的方法。
    除了它们之外,还有指令的controller 属性和ngRoutecontroller 属性,你根本没有提到。

    (3) 是一种使用 Angular 的 DI 注册控制器实现的方法(它负责实例化绑定到特定元素的控制器。
    从这个意义上说,通过函数名称自动匹配控制器实现(您所说的 (autodiscovery) 是 (3) 的替代方法,所以我们将其命名为 (4)。

    根据上述,(1) 和 (2) 不是 (3) 和 (4) 的替代方法,但它们都是必需的,并且是相辅相成的。


    从上述功能来看,“自动发现”是我最不想依赖的功能。
    它感觉很hacky/不是很“健壮”,其目的是减少快速组合小型原型或示例所需的代码,而不是用于大规模生产应用程序。

    来自 Angular 的 Developer Guide

    注意:虽然 Angular 允许您在全局范围内创建 Controller 函数,但不建议这样做。在实际应用程序中,您应该为您的应用程序使用 Angular 模块的 .controller 方法 [...]


    IMO,真正的争论是关于 controllercontoller as

    以下是一些注意事项:

    1. controller as 功能是一项新功能,可能仍在评估中。它可能会留下来,但我不会把所有的钱都押在上面。

    2. controller as 语法中,没有实际的$scope(即Scope 对象,$rootScope 的后代等)。这一事实对您如何执行某些$scope 特定的东西有一些影响,例如使用$on()$watching 等属性注册监听器。

    3. controller as 语法可能会提高视图的可维护性/可读性,因为它明确每个属性所指的控制器 - 它避免了属性通过原型继承、被覆盖等可用的情况。另一方面另一方面,原型继承的缺失限制了数据的传播方式。


    也就是说,我对controller 语法有一点偏好,因为我发现$scope 提供的实用程序很有用,而且我在我的项目中没有发现任何可以使controller as 语法更受欢迎的用例。

    【讨论】:

    • 好吧,我得争论一下:-) 我确实理解编程语言中declarationdefinition 的概念,在Angular 中也是如此。我知道 1 和 2 是用于绑定的方法,但我的问题是关于选择一个而不是另一个。 3 和 4,同意,它们是互补的,但绝对是 NOT NEEDED 因为自动匹配。对我来说,不太健壮的恰好是 3 和 4,因为我需要额外的代码才能使其工作(违反配置约定)。至于最后一个问题——你确定this 在使用controller as 语法时实际上不是$scope
    • 1) 您的问题看起来像是您认为 (3) 是 (1) 和 (2) 的替代方法(显然不是;这是完全不同的事情)。作为(4)我指的是自动发现(不是你的3b)。 (3) 或 (4) is 绝对必要((4) 是您的“自动发现” - 因此您需要依赖自动发现 (4) 或显式注册控制器 (3) -但两者之一是绝对必要的)。附加代码并不意味着不那么健壮(一行的附加代码并没有太大的开销)。
    • 您是否考虑过在全局范围内定义与您的控制器同名的函数的第 3 方库的含义?自动发现更容易出错(因此不太稳健)。最后,是的,我很确定this 不是$scope
    • 抱歉,对于长 cmets,但有很多主题要涵盖 :) 正如我所说,我认为自动发现不是是“生产就绪”,但是是个人判断,其他人可能会不这么认为(我会寻找更多“确凿的证据来支持我的观点并在我发现任何东西时进行更新)。对我来说,真正的困境是controller vs controller as。我提到了那里的差异是(以及我的考虑)——正如我所说,我对两者都没有强烈的感情(但我使用并略微偏爱前者)。
    • 是的,我意识到我的 1..3 列表可能被视为替代品,这不是我的意图。会解决的。名称冲突是不太可能发生的,我不会因为害怕遇到问题而牺牲代码的可读性和易于维护。我真的很喜欢“自动发现”,但我仍然找不到任何反对它的东西:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多