在Vojta Jina的优秀存储库中,他在其中演示了指令的测试,他在模块包装器之外定义了指令控制器。看到这里:https : //github.com/vojtajina/ng- directive-testing/blob/master/js/tabs.js
这不是不好的做法并且会污染全局名称空间吗?
如果在另一个地方可以合理地调用TabsController,那会不会很麻烦?
可以在此处找到针对上述指令的测试:https : //github.com/vojtajina/ng-directive- testing/commit/test-controller
是否可以将指令控制器与指令的其余部分分开测试,而无需将控制器放在全局命名空间中?
将整个指令封装在app.directive(…)定义中会很好。
很好的问题!
因此,这是一个普遍的关注点,不仅对于控制器而言,而且对于指令可能需要执行其工作但不一定要将该控制器/服务暴露给“外部世界”的服务而言,都是潜在的问题。
我坚信 全局数据是有害的,应避免使用,这也适用于指令控制器 。如果采用这种假设,我们可以采用几种不同的方法来“本地”定义那些控制器。在这样做的时候,我们需要记住, 控制器应该仍然可以“轻松”地用于单元测试, 因此我们不能简单地将其隐藏在指令的闭包中。IMO的可能性是:
1)首先,我们可以简单地 在模块级别上定义指令的控制器 ,例如:
angular.module('ui.bootstrap.tabs', []) .controller('TabsController', ['$scope', '$element', function($scope, $element) { ... }]) .directive('tabs', function() { return { restrict: 'EA', transclude: true, scope: {}, controller: 'TabsController', templateUrl: 'template/tabs/tabs.html', replace: true }; })
这是我们基于Vojta的工作在https://github.com/angular- ui/bootstrap/blob/master/src/tabs/tabs.js中使用的一种简单技术。
尽管这是一种非常简单的技术,但应注意,控制器仍然暴露于整个应用程序中,这意味着其他模块可能会覆盖它。从这个意义上讲,它使控制器对于AngularJS应用程序是本地的(因此不会污染全局窗口范围),但对于所有AngularJS模块也是全局的。
2) 使用闭包范围和特殊文件设置进行测试 。
如果要完全隐藏控制器功能,可以将代码包装在闭包中。这是AngularJS使用的技术。例如,查看NgModelController,我们可以看到它在自己的文件中被定义为“全局”函数(因此可以轻松地进行测试),但是整个文件在构建期间都被封装在闭包中:
综上所述:选项(2)比较“安全”,但是需要一些先期的构建步骤。