【问题标题】:Globally defined AngularJS controllers and encapsulation全局定义的 AngularJS 控制器和封装
【发布时间】:2012-11-13 14:53:07
【问题描述】:

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

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

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

    Object.functionName();

而不是这样:

    functionName();

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

【问题讨论】:

    标签: javascript angularjs encapsulation


    【解决方案1】:

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

    angular.module('[module name]', []).controller('PhoneListCtrl', function($scope) {
    
      $scope.phones = [..];
    
      $scope.orderProp = 'age';
    });
    

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

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

    【讨论】:

    • 谢谢!这正是我正在寻找的解释类型。继续努力!
    • 文档中应该提到很多东西,哈哈。我想这就是学习 AngularJS 的乐趣所在,就像寻宝一样。
    • 文档不够用,因为它还是新的;至少这就是我的假设。我真的希望他们开始编写详尽的文档,因为他们的文档中缺少大量内容。他们没有 API 中列出的所有可用函数!
    • 这是否也能解决缩小问题?
    • 不,缩小问题是正交的。为了缩小您需要使用数组样式的符号:docs.angularjs.org/guide/di 和此处的代码示例:github.com/angular-app/angular-app/blob/master/client/src/app/…
    【解决方案2】:

    您可以按照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的“测试控制器”下找到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-02
      • 2013-07-21
      • 2014-09-26
      • 2016-12-04
      • 1970-01-01
      • 2015-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多