【问题标题】:Should one avoid including regular Javascript objects in AngularJS controllers?是否应该避免在 AngularJS 控制器中包含常规 Javascript 对象?
【发布时间】:2015-02-05 18:33:06
【问题描述】:

我正在阅读 Adam Freeman 的 Pro AngularJS,我对书中的一个例子有一个挑剔的问题:

myApp.controller("tomorrowCtrl", function($scope) {
    var dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday";]
    $scope.day = dayNames[(new Date().getDay() + 1) % 7];    
});

我了解这个控制器的总体目的是:通过$scope.day 在视图上显示星期几的名称。但我很困惑为什么控制器使用普通的 Javascript 数组 - var dayNames - 来创建 $scope 对象。

AngularJS controller documentation 解释说控制器用于:

设置 $scope 对象的初始状态 [并] 向 $scope 对象添加行为。

果然,dayNames 有助于设置 $scope 对象的初始状态。它还包含一些应用程序的业务逻辑,所以我猜它有点检查出来。我担心的是我还没有找到任何其他遵循这种设计模式的 AngularJS 控制器示例。我在 Angular 控制器文档和 PhoneCat 教程中都没有找到任何内容。

像这样在 AngularJS 控制器中包含普通的 Javascript 对象有意义吗? (这被认为是无害的吗?)

如果不是,为什么? 是否有充分的理由在控制器中包含普通的 Javascript 对象?此外,dayNames 是否有其他方式适合 Angular 架构,例如指令或服务?

【问题讨论】:

  • 我猜他们没有理由公开 dayNames 所以他们没有将它绑定到 $scope?

标签: javascript angularjs


【解决方案1】:

您会在书籍和互联网上看到很多类似的例子。关键是 $scope.day 设置为 something,我确定它如何在您的 view 中反映出来。

您可以拥有外部纯 Javascript 逻辑并在 angularJS 中使用它,它显然不会破坏任何东西,但通常最好在控制器之外完成所有范围操作/业务逻辑服务/工厂/供应商。为什么要反对 angularJS 并使用外部的东西?你想坚持 angularJS 的流程。

假设它正在做一些更复杂的事情,它可能看起来更像这样:

myApp.factory("tomorrowService", function() {
    // factory's can be written in many different patterns
    // this is just for examples sake
    return {
        getDays : function () { /* return stuff */ }
    }
});

myApp.controller("tomorrowCtrl", function($scope, tomorrowService) {
    $scope.day = tomorrowService.getDays();    
});

使用tomorrowService 中的方法执行所有业务逻辑并返回某种结果。

我发现这篇文章 (http://toddmotto.com/rethinking-angular-js-controllers/) 非常有用,有助于更好地了解如何制作控制器以及在 angularJS 项目中有益的分离。

【讨论】:

  • 对于 nitpick,它应该正确命名为 tomorrowService - 工厂只是生成服务实例的函数:)
  • 我打字太快了。你赢了:) 修复了@NewDev
【解决方案2】:
  1. 此数据是否仅属于该控制器而不属于其他任何地方 应用?
  2. 此数据是否直接支持视图模型的生成(而不是业务逻辑)?
  3. 这是否会创建一个“胖”控制器(即使代码难以理解)?

(不知道列表是否全面)

如果答案是“否”,那么保留它可能是可以的。

并非所有内容都必须在 $scope 上。我有时会在问题中看到这一点:

$scope.init = function(){
  // do some initialization
}

$scope.init();

显然,没有理由将init 附加到作用域上,最好将其声明为控制器中定义的命名函数:

function init(){
}

init();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多