¿Alguien puede decirme cómo incluir un controlador de una directiva en otra directiva angularJS? por ejemplo tengo el siguiente 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);
}
};
});
Según todas las cuentas, debería poder acceder al controlador en la directiva addProduct, pero no lo soy. ¿Existe una mejor manera de hacer esto?
javascript
angularjs
angularjs-directive
Le Garden Fox
fuente
fuente
require
asegura la presencia de otra directiva y luego incluye su controlador.^require
comprueba los elementos por encima del actual además del elemento actual. Por lo tanto, debe usar las dos directivas juntas para que esto funcione. De lo contrario, simplemente defina un controlador conapp.controller
y luego úselo en ambas directivas. De cualquier manera, ¿puedes poner esto en un Plunker simple junto con tu código HTML?Respuestas:
Tuve suerte y respondí esto en un comentario a la pregunta, pero estoy publicando una respuesta completa en aras de la integridad y para que podamos marcar esta pregunta como "Respondida".
Depende de lo que desee lograr al compartir un controlador; puede compartir el mismo controlador (aunque tenga diferentes instancias), o puede compartir la misma instancia de controlador.
Compartir un controlador
Dos directivas pueden usar el mismo controlador pasando el mismo método a dos directivas, así:
app.controller( 'MyCtrl', function ( $scope ) { // do stuff... }); app.directive( 'directiveOne', function () { return { controller: 'MyCtrl' }; }); app.directive( 'directiveTwo', function () { return { controller: 'MyCtrl' }; });
Cada directiva obtendrá su propia instancia del controlador, pero esto le permite compartir la lógica entre tantos componentes como desee.
Requerir un controlador
Si desea compartir la misma instancia de un controlador, utilice
require
.require
asegura la presencia de otra directiva y luego incluye su controlador como parámetro para la función de enlace. Entonces, si tiene dos directivas en un elemento, su directiva puede requerir la presencia de la otra directiva y obtener acceso a sus métodos de controlador. Un caso de uso común para esto es requirengModel
.^require
, con la adición del signo de intercalación, comprueba los elementos anteriores a la directiva además del elemento actual para tratar de encontrar la otra directiva. Esto le permite crear componentes complejos donde los "subcomponentes" pueden comunicarse con el componente principal a través de su controlador con gran efecto. Los ejemplos podrían incluir pestañas, donde cada panel puede comunicarse con las pestañas generales para manejar el cambio; un juego de acordeón podría asegurar que solo uno esté abierto a la vez; etc.En cualquier caso, debe utilizar las dos directivas juntas para que esto funcione.
require
es una forma de comunicarse entre componentes.Consulte la página de la Guía de directivas para obtener más información: http://docs.angularjs.org/guide/directive
fuente
require
para especificar una sola directiva, o una matriz de directivas; cada directiva puede tener un prefijo de intercalación (^
) para requisitos más granulares)Hay una buena respuesta de stackoverflow aquí por Mark Rajcok:
Controladores de directiva AngularJS que requieren controladores de directiva principal
con un enlace a este jsFiddle muy 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'; }
fuente