28

根据 AngularJS 的教程,控制器函数只是位于全局范围内。

http://docs.angularjs.org/tutorial/step_04

控制器函数本身会自动解析到封装范围内,还是驻留在全局范围内?我知道他们被传递了对他们自己的 $scope 的引用,但似乎函数本身只是位于全局范围内。显然,这可能会导致问题,我通过经验和教育学到了封装此外,如果它们确实存在于全局范围内,那么将它们封装在要像这样引用的对象中是否不被认为是最佳实践:

    Object.functionName();

而不是这样:

    functionName();

以防止由于全局范围的污染(即覆盖函数等)而发生的问题。

4

2 回答 2

53

AngularJS 支持两种注册控制器函数的方法——作为全局可访问的函数(你可以在提到的教程中看到这种形式)或作为模块的一部分(形成一种命名空间)。有关模块的更多信息可以在这里找到:http: //docs.angularjs.org/guide/module但简而言之,可以在模块中注册一个控制器,如下所示:

angular.module('[module name]', []).controller('PhoneListCtrl', function($scope) {

  $scope.phones = [..];

  $scope.orderProp = 'age';
});

AngularJS 在许多示例中使用声明控制器的简短的全局函数形式,但是虽然这种形式有利于快速示例,但不应该在实际应用程序中使用

简而言之:AngularJS 使得正确封装控制器函数成为可能,但也公开了一种更简单、快速和肮脏的方式来将它们声明为全局函数。

于 2012-11-13T15:23:11.713 回答
19

正如pkozlowski-opensource所回答的那样,您可以将控制器注册为模块的一部分。

如果您需要缩小,您可以通过在列表中的实际函数之前提供变量名称来简单地扩展它:

angular.module('[module name]', []).
  controller('PhoneListCtrl', ['$scope', function($scope) {

    $scope.phones = [..];
    $scope.orderProp = 'age';
  }]);

这将在“缩小”之后工作相同:

angular.module('[module name]', []).
  controller('PhoneListCtrl', ['$scope', function(s) {

    s.phones = [..];
    s.orderProp = 'age';
  }]);

这个符号可以在Dependency Injection的“Inline Annotation”下找到。

要测试已注册为模块一部分的控制器,您必须要求 Angular 来创建您的控制器。例如:

describe('PhoneListCtrl test', function() {
  var scope;
  var ctrl;

  beforeEach(function() {
    module('[module name]');
    inject(function($rootScope, $controller) {
      scope = $rootScope.$new();
      ctrl = $controller('[module name]', {$scope: scope});
    });
  });

  it('should be ordered by age', function() {
    expect(scope.orderProp).toBe('age');
  });

});

这种测试控制器的方法可以在了解控制器组件的“测试控制器”下找到。

于 2013-01-08T09:42:43.247 回答