Может ли кто-нибудь сказать мне, как включить контроллер из одной директивы в другую директиву 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, но это не так. Есть ли лучший способ сделать это?
javascript
angularjs
angularjs-directive
Le Garden Fox
источник
источник
require
обеспечивает наличие другой директивы и затем включает ее контроллер.^require
проверяет элементы выше текущего в дополнение к текущему элементу. Таким образом, вы должны использовать две директивы вместе, чтобы это работало. В противном случае просто определите контроллер с помощью,app.controller
а затем используйте его в обеих директивах. В любом случае, можете ли вы поместить это в простой Plunker вместе со своим HTML-кодом?Ответы:
Мне повезло, и я ответил на это в комментарии к вопросу, но я публикую полный ответ для полноты, поэтому мы можем отметить этот вопрос как «Отвеченный».
Это зависит от того, чего вы хотите достичь, поделившись контроллером; вы можете использовать один и тот же контроллер (хотя и иметь разные экземпляры) или один и тот же экземпляр контроллера.
Поделиться контроллером
Две директивы могут использовать один и тот же контроллер, передав один и тот же метод двум директивам, например:
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
с добавлением каретки проверяет элементы выше директивы в дополнение к текущему элементу, чтобы попытаться найти другую директиву. Это позволяет вам создавать сложные компоненты, в которых «подкомпоненты» могут взаимодействовать с родительским компонентом через его контроллер для достижения большого эффекта. Примеры могут включать вкладки, где каждая панель может взаимодействовать с общими вкладками для управления переключением; гармошка могла гарантировать, что одновременно будет работать только один; и т.п.В любом случае вы должны использовать две директивы вместе, чтобы это работало.
require
это способ связи между компонентами.Дополнительную информацию см. На странице руководства по директивам: http://docs.angularjs.org/guide/directive
источник
require
для указания одной директивы или массива директив; каждая директива может иметь префикс каретки (^
) для болееЗдесь есть хороший ответ на 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'; }
источник