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

任何人都可以告诉我如何在另一个angularJS指令中包含来自一个指令的控制器。 例如我有以下代码

var app = angular.module('shop', []). config(['$routeProvider', function ($routeProvider) { $routeProvider.when('/', { templateUrl: '/js/partials/home.html' }) .when('/products', { controller: 'ProductsController', templateUrl: '/js/partials/products.html' }) .when('/products/:productId', { controller: 'ProductController', templateUrl: '/js/partials/product.html' }); }]); app.directive('mainCtrl', function () { return { controller: function ($scope) {} }; }); app.directive('addProduct', function () { return { restrict: 'C', require: '^mainCtrl', link: function (scope, lElement, attrs, mainCtrl) { //console.log(cartController); } }; }); 

所有帐户,我应该能够访问控制器的addProduct指令,但我不是。 有没有更好的方法来做到这一点?

我很幸运,在回答这个问题的时候回答了这个问题,但为了完整起见,我发布了一个完整的答案,所以我们可以把这个问题标记为“已回答”。


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

共享一个控制器

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

 app.controller( 'MyCtrl', function ( $scope ) { // do stuff... }); app.directive( 'directiveOne', function () { return { controller: 'MyCtrl' }; }); app.directive( 'directiveTwo', function () { return { controller: 'MyCtrl' }; }); 

每个指令都将获得自己的控制器实例,但是这允许您在任意数量的组件之间共享逻辑。

需要一个控制器

如果你想共享一个控制器的同一个实例 ,那么你使用require

require确保存在另一个指令,然后将其控制器作为链接函数的参数。 所以,如果你在一个元素上有两个指令,你的指令可以要求另一个指令的存在并访问它的控制器方法。 一个常见的用例是要求ngModel

^require ,加上插入符,除了当前元素之外,还要检查指令上面的元素,以试图find另一个指令。 这使您可以创build复杂的组件,其中“子组件”可以通过其控制器与父组件进行通信,以达到最佳效果。 示例可以包括选项卡,其中每个窗格可以与整个选项卡进行通信以处理切换; 一套手风琴可以保证一次只能打开一个; 等等

无论哪种情况,你都必须一起使用这两个指令才能工作。 require是组件之间沟通的一种方式。

查看更多信息的指导指南页面: http : //docs.angularjs.org/guide/directive

Mark Rajcok在这里有一个很好的stackoverflow答案:

需要父指令控制器的AngularJS指令控制器?

与这个非常清晰的jsFiddle链接: http : //jsfiddle.net/mrajcok/StXFK/

 <div ng-controller="MyCtrl"> <div screen> <div component> <div widget> <button ng-click="widgetIt()">Woo Hoo</button> </div> </div> </div> </div> 

JavaScript的

 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'; }