【发布时间】:2015-04-14 15:01:54
【问题描述】:
我正在尝试创建一个需要使用单独控制器的自定义指令,因为它需要具有可由子指令调用的函数。
到目前为止,这是我的代码:
angular.module('myDirectives').controller('SlideInMenuController', function ($scope, $element, $attrs) {
$scope.isOpen = false;
// Toggle Function
this.toggle = function(){
$scope.$apply(function(){
$scope.isOpen = !$scope.isOpen;
});
};
// Watch $scope.isOpen and open the menu
$scope.$watch('isOpen', function() {
if($scope.isOpen == true){
$element.attr('is-open', true);
}
else{
$element.attr('is-open', false);
}
return false;
});
}
angular.module('myDirectives').directive('slideInMenu', function ($swipe) {
return {
restrict: 'EA',
scope: {},
controller:'SlideInMenuController'
};
});
angular.module('myDirectives').directive('slideInMenuToggle', function ($swipe) {
return {
restrict: 'EA',
require: '^slideInMenu',
link: function ($scope, $element, $attrs, SlideInMenuCtrl) {
$element.bind('click', function(){
SlideInMenuCtrl.toggle();
});
}
};
});
(注意:我使用的是 ng-annotate,所以我不必将所有依赖项都写两次)
我需要将 $swipe 服务注入指令控制器,但普通控制器不会将 $scope、$element、$attrs 作为前三个参数。这让我想知道我是否应该将它们放入链接函数并在那里做 DOM 的东西,但如果我这样做,控制器中的内容和链接函数中的内容。
我已经阅读了许多博客和 SO 答案,其中说明了编译/链接/控制器的运行顺序,但仍然找不到关于我上面的示例应该去哪里的明确答案。
任何帮助将不胜感激。
【问题讨论】:
-
“我需要注入 $swipe 服务”:继续,这完全合理。 “但普通控制器不会......”:您的控制器是旨在由指令使用的控制器;再次完全合理地依赖于指令特定的东西。 (顺便说一句,上面的代码没有使用
$attrs,你可以删除它。)你的实现对我来说似乎很好——除了一件事:我宁愿从element.bind调用$apply,它在Angular外部调用而不是来自SlideInMenuController.toggle。还是我错过了一点? -
因此,通常依赖项可以按任何顺序注入。我认为 $scope、$element 和 $attrs 的顺序必须正确,因为它们是正常的函数参数,而不是注入的依赖项。如果它们就像任何其他依赖项一样,那么它们可以按任何顺序排列,例如 ($swipe, $element, $scope)?如果是这样,那么为什么有些人在没有美元符号的情况下调用它们(范围、元素、属性)?
-
至于$scope.$apply,我不完全明白为什么我把它放在我放的地方。我只知道我必须把它放在那里才能让它工作;-)如果你认为这更有意义,我可以尝试将它移动到切换指令中的绑定。
-
嗨,请参阅 Werlang 答案中的有效点,并且:1)是的,link 函数需要按特定顺序的参数。控制器按您要求的顺序注入依赖项。并且名称无关紧要,您可以使用
['$http', function($q) {...}]和$q将是$http服务(如果您喜欢痛苦,这是一个不错的选择,例如 C 中的#define TRUE FALSE:) -
2) 对于
$apply:是的,对我来说更有意义:bind是从 Angular 外部(直接从浏览器)调用的。它必须通知 Angular 才能进行脏检查。原则上,控制器的方法可以从 Angular 内部调用。在这种情况下,您将收到digest already in progress错误。
标签: javascript angularjs