Javascript 如何在angularjs指令中要求控制器

Javascript 如何在angularjs指令中要求控制器,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,谁能告诉我如何将一个指令中的控制器包含在另一个angularJS指令中。 例如,我有以下代码 var-app=angular.module('shop',[])。 配置(['$routeProvider',函数($routeProvider){ $routeProvider.when(“/”{ templateUrl:“/js/partials/home.html” }) 。当(“/产品”{ 控制器:“ProductsController”, templateUrl:“/js/partials/

谁能告诉我如何将一个指令中的控制器包含在另一个angularJS指令中。 例如,我有以下代码

var-app=angular.module('shop',[])。
配置(['$routeProvider',函数($routeProvider){
$routeProvider.when(“/”{
templateUrl:“/js/partials/home.html”
})
。当(“/产品”{
控制器:“ProductsController”,
templateUrl:“/js/partials/products.html”
})
.when(“/products/:productId”{
控制器:“ProductController”,
templateUrl:“/js/partials/product.html”
});
}]);
应用程序指令('mainCtrl',函数(){
返回{
控制器:函数($scope){}
};
});
应用指令('addProduct',函数(){
返回{
限制:“C”,
要求:“^mainCtrl”,
链接:函数(作用域、lement、attrs、mainCtrl){
//console.log(cartController);
}
};
});

无论如何,我应该能够访问addProduct指令中的控制器,但我不能。有更好的方法吗

我很幸运,在对问题的评论中回答了这个问题,但为了完整起见,我发布了完整的答案,因此我们可以将这个问题标记为“已回答”


这取决于你想通过共享一个控制器来完成什么;您可以共享同一控制器(尽管有不同的实例),也可以共享同一控制器实例

共享控制器

通过将相同的方法传递给两个指令,两个指令可以使用相同的控制器,如下所示:

app.controller('MyCtrl',函数($scope){
//做些事情。。。
});
应用程序指令('directiveOne',函数(){
返回{
控制器:“MyCtrl”
};
});
app.directive('directiveTwo',function(){
返回{
控制器:“MyCtrl”
};
});
每个指令将获得自己的控制器实例,但这允许您在任意多个组件之间共享逻辑

需要控制器

如果要共享同一控制器实例,请使用
require


require
确保存在另一个指令,然后将其控制器作为参数包含到链接功能中。因此,如果您在一个元素上有两个指令,那么您的指令可以要求另一个指令的存在,并获得对其控制器方法的访问权。这方面的一个常见用例是需要
ngModel

^require
,在添加插入符号后,除了当前元素外,还会检查指令上方的元素,以尝试查找其他指令。这允许您创建复杂的组件,其中“子组件”可以通过其控制器与父组件通信,效果非常好。示例包括选项卡,其中每个窗格可以与整个选项卡通信以处理切换;手风琴套件可以确保一次只能打开一个;等等

在任何一种情况下,您都必须同时使用这两个指令才能使其工作<代码>要求是组件之间通信的一种方式


查看指令指南页面了解更多信息:

Mark Rajcok给出了一个很好的stackoverflow答案:

有一个指向这个非常清晰的JSFIDLE的链接:


require
确保存在另一个指令,然后包括其控制器
^require
检查当前元素和当前元素之上的元素。因此,您必须同时使用这两个指令才能工作。否则,只需使用
app.controller
定义一个控制器,然后在两个指令中使用它。无论哪种方式,您都可以将其与HTML代码一起放入一个简单的Plunk中吗?是否可能需要一个同级指令控制器?基本上,我需要在同级指令(如DOM同级指令,而不是在同一DOM元素上)之间共享使用ng repeat重复的控制器或服务的相同实例。假设每个重复的项目都有一个指令,它们之间需要共享状态或逻辑。@CMCDRANGKAI没有办法做到这一点,但有两种常见的方法来完成相同的事情。第一个是,如果同级都是相同的“类型”,那么ngRepeat上面的元素可以像一个容器指令,所有子元素可以要求该指令,而不是共享同一个控制器。更常见的解决方案(通常更规范)是使用共享服务。你能详细说明一下这些兄弟姐妹做什么以及他们需要分享什么吗?是的,他们最后做了第一个选择。使用容器指令控制器。效果很好。这是一个很好的答案,并巩固了我对所有这些工作原理的理解。谢谢(请注意,这可能是一个较新的功能,但您可以使用
require
指定单个指令或指令数组;每个指令都可以加上插入符号(
^
)作为前缀,以满足更精细的要求。)在两个指令中使用同一控制器并不会给每个指令提供它自己的实例。对我来说,MarkRajcok的示例之所以最受欢迎,是因为他关注控制器方法的创建方式。通常,您会看到通过$scope.methodName=function(){…}创建的控制器方法,但为了使其正常工作,您必须对希望访问的方法使用this.methodName。一开始我没有注意到。
<div ng-controller="MyCtrl">
    <div screen>
        <div component>
            <div widget>
                <button ng-click="widgetIt()">Woo Hoo</button>
            </div>
        </div>
    </div>
</div>
var myApp = angular.module('myApp',[])

.directive('screen', function() {
    return {
        scope: true,
        controller: function() {
            this.doSomethingScreeny = function() {
                alert("screeny!");
            }
        }
    }
})

.directive('component', function() {
    return {
        scope: true,
        require: '^screen',
        controller: function($scope) {
            this.componentFunction = function() {
                $scope.screenCtrl.doSomethingScreeny();
            }
        },
        link: function(scope, element, attrs, screenCtrl) {
            scope.screenCtrl = screenCtrl
        }
    }
})

.directive('widget', function() {
    return {
        scope: true,
        require: "^component",
        link: function(scope, element, attrs, componentCtrl) {
            scope.widgetIt = function() {
                componentCtrl.componentFunction();
            };
        }
    }
})


//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});

function MyCtrl($scope) {
    $scope.name = 'Superhero';
}