Alguém pode me dizer como incluir um controlador de uma diretiva em outra diretiva angularJS. por exemplo, eu tenho o seguinte código
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);
}
};
});
Eu deveria ser capaz de acessar o controlador na diretiva addProduct, mas não sou. Existe um jeito melhor de fazer isso?
javascript
angularjs
angularjs-directive
Le Garden Fox
fonte
fonte
require
garante a presença de outra diretiva e, em seguida, inclui seu controlador.^require
verifica os elementos acima do atual, além do elemento atual. Portanto, você tem que usar as duas diretivas juntas para que isso funcione. Caso contrário, apenas defina um controlador comapp.controller
e, em seguida, use-o em ambas as diretivas. De qualquer maneira, você pode colocar isso em um Plunker simples junto com seu código HTML?Respostas:
Tive sorte e respondi com um comentário sobre a pergunta, mas estou postando uma resposta completa por uma questão de integridade e, portanto, podemos marcar essa pergunta como "Respondida".
Depende do que você deseja realizar compartilhando um controlador; você pode compartilhar o mesmo controlador (embora tenha instâncias diferentes) ou pode compartilhar a mesma instância do controlador.
Compartilhe um controlador
Duas diretivas podem usar o mesmo controlador passando o mesmo método para duas diretivas, assim:
app.controller( 'MyCtrl', function ( $scope ) { // do stuff... }); app.directive( 'directiveOne', function () { return { controller: 'MyCtrl' }; }); app.directive( 'directiveTwo', function () { return { controller: 'MyCtrl' }; });
Cada diretiva obterá sua própria instância do controlador, mas isso permite que você compartilhe a lógica entre quantos componentes desejar.
Requer um controlador
Se você quiser compartilhar a mesma instância de um controlador, use
require
.require
garante a presença de outra diretiva e, em seguida, inclui seu controlador como um parâmetro para a função de link. Portanto, se você tiver duas diretivas em um elemento, sua diretiva pode exigir a presença da outra diretiva e obter acesso aos seus métodos de controlador. Um caso de uso comum para isso é exigirngModel
.^require
, com a adição do acento circunflexo, verifica os elementos acima da diretiva, além do elemento atual, para tentar encontrar a outra diretiva. Isso permite criar componentes complexos onde "subcomponentes" podem se comunicar com o componente pai por meio de seu controlador com grande efeito. Os exemplos podem incluir guias, onde cada painel pode se comunicar com as guias gerais para lidar com a alternância; um conjunto de acordeão pode garantir que apenas um seja aberto por vez; etc.Em qualquer caso, você deve usar as duas diretivas juntas para que isso funcione.
require
é uma forma de comunicação entre componentes.Confira a página de diretivas do Guia para mais informações: http://docs.angularjs.org/guide/directive
fonte
require
para especificar uma única diretiva ou uma série de diretivas; cada diretiva pode ser prefixada com um acento circunflexo (^
) para requisitos mais granulares.)Há uma boa resposta stackoverflow aqui por Mark Rajcok:
Controladores diretivos AngularJS que requerem controladores diretivos pai?
com um link para este jsFiddle muito claro: 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'; }
fonte