AngularJS:声明控制器vs不声明控制器



我正在遵循AngularJS网站上的教程,目前我的控制器如下,页面加载完美:

var phonecatApp = angular.module('phonecatApp', []);
phonecatApp.controller('PhoneListCtrl', function($scope, $http) {
  $http.get('phones/phones.json').success(function(data) {
    $scope.phones = data;
  });
  $scope.orderProp = 'age';
});

当我在做步骤5的"A Note on Minification"部分时,我想到了这个:

var phonecatApp = angular.module('phonecatApp', []);
function PhoneListCtrl($scope, $http) {
  $http.get('phones/phones.json').success(function(data) {
    $scope.phones = data;
  });
  $scope.orderProp = 'age';
}
//phonecatApp.controller('PhoneListCtrl', ['$scope', '$http', PhoneListCtrl]);

页面加载了第二段代码,我在其中注释了模块中控制器的创建。我的问题是,从模块中声明控制器和定义函数

有什么区别?

实际执行/行为没有区别,第二个是使用称为"函数构造器"的东西。这是在javascript中创建类结构的常用方法。

下面的第一个将做同样的事情,只是angularJs的依赖注入模型与字符串一起工作,所以它更容易阅读。

声明一个全局函数,AFAIK是可能的,以便简化简单的演示并快速上手。在最新版本的Angular中,默认不再支持它(参见https://github.com/angular/angular.js/commit/3f2232b5a181512fac23775b1df4a6ebda67d018)。

用大量的函数污染全局命名空间是不好的做法。

查看Todd Motto的angular风格指南:http://toddmotto.com/opinionated-angular-js-styleguide-for-teams/

将控制器定义为函数表达式对于保持代码DRY和允许命名堆栈跟踪非常重要:

function PhoneListCtrl($scope, $http) {
  $http.get('phones/phones.json').success(function(data) {
    $scope.phones = data;
  });
  $scope.orderProp = 'age';
}

问题是这将函数置于全局作用域中;呵呵人参公鸡。解决方案是将声明封装在IIFE中。这允许您保持定义函数的最佳实践,并且不会污染全局作用域。

下面是一个例子:

(function () {
  angular.module('app', []);
  // MainCtrl.js
  function MainCtrl () {
  }
  angular
    .module('app')
    .controller('MainCtrl', MainCtrl);
  // AnotherCtrl.js
  function AnotherCtrl () {
  }
  angular
    .module('app')
    .controller('AnotherCtrl', AnotherCtrl);
  // and so on...
})();

像这样:

function PhoneListCtrl($scope, $http) {

你的函数将在global作用域中声明。

我们知道污染全局作用域显然是不好的,因为它可能导致变量/函数冲突。

最新更新