全局定义的AngularJS控制器和封装

时间:2012-11-13 14:53:07

标签: javascript angularjs encapsulation

根据AngularJS的教程,控制器功能仅位于全局范围内。

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

控制器功能本身是否自动被解析为封装范围,还是它们居住在全球范围内?我知道他们传递了对自己的$ scope的引用,但看起来这个函数本身只是坐在全局范围内。显然,这可能会导致问题,我已经通过经验和教育来学习封装。此外,如果他们确实居住在全球范围内,那么将它们封装在要引用的对象中是不是最佳实践:

    Object.functionName();

而不是:

    functionName();

以防止全球范围内的污染问题(即重写功能等)。

2 个答案:

答案 0 :(得分:53)

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

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

  $scope.phones = [..];

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

AngularJS在许多示例中使用了一种简短的全局函数形式的声明控制器,但是这种形式适用于快速采样,而不应该在实际应用中使用

简而言之:AngularJS可以正确封装控制器功能,但也可以简化,快速和简单。将它们宣布为全局函数的肮脏方式。

答案 1 :(得分: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

要测试已注册为模块一部分的控制器,您必须要求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');
  });

});

这种测试控制器的方法可以在"测试控制器"在Understanding the Controller Component