personalizadas directivas crear angularjs angularjs-directive angularjs-scope

crear - ¿Controladores de directivas AngularJS que requieren controladores de directivas principales?



directivas personalizadas angular 5 (4)

Podría estar pensando en esto completamente al revés, pero estoy tratando de hacer tres directivas anidadas, llamémoslas: pantalla, componente y widget. Quiero que el widget pueda desencadenar algún comportamiento en el componente, que a su vez desencadena algún comportamiento en la pantalla. Asi que:

.directive(''screen'', function() { return { scope: true, controller: function() { this.doSomethingScreeny = function() { alert("screeny!"); } } } }) .directive(''component'', function() { return { scope: true, controller: function() { this.componentFunction = function() { WHAT.doSomethingScreeny(); } } } }) .directive(''widget'', function() { return { scope: true, require: "^component", link: function(scope, element, attrs, componentCtrl) { scope.widgetIt = function() { componentCtrl.componentFunction(); }; } } }) <div screen> <div component> <div widget> <button ng-click="widgetIt()">Woo Hoo</button> </div> </div> </div>

Puedo requerir componentes principales en el enlace de un widget fn using require: "^component" , pero ¿cómo puedo darle acceso a los controladores de componentes a su pantalla contenedora?

Lo que necesito es el componente QUÉ en el componente, de modo que cuando hace clic en el botón del widget, se alerta "¡pantalla!".

Gracias.


Aquí hay dos maneras en que podría resolver su problema:

  1. Como está utilizando scope: true , todos los ámbitos se heredan prototípicamente. Por lo tanto, si define sus métodos en $scope lugar de this en el controlador de screen , ambos tendrán acceso a la función doSomethingScreeny .
    Fiddle
  2. Defina una función de enlace en el component y require: ''^screen'' . En la función de enlace, guarde el screenCtrl en una propiedad de ámbito, luego puede acceder a él en el controlador de la directiva (inject $scope ).
    Fiddle

La mayoría de estas cosas fallan cuando desea acceder directamente a las propiedades o métodos desde el controlador principal en la creación del controlador. Encontré otra solución utilizando la inyección de dependencia y el servicio $controller .

.directive(''screen'', function ($controller) { return { require: ''^parent'', scope: {}, link: function (scope, element, attr, controller) { $controller(''MyCtrl'', { $scope: scope, $element: element, $attr, attr, controller: controller }); } } }) .controller(''MyCtrl, function ($scope, $element, $attr, controller) {});

Este método es mejor comprobable y no contamina su alcance con controladores no deseados.


return {scope: true} o return {scope: false} no afecta a la variable $ scope en controller: function ($ scope) {} en cada directiva, pero la etiqueta de la directiva debe colocarse en la etiqueta ng-controller o ng-app .

Fiddle

Fiddle


var myApp = angular.module(''myApp'', []) .directive(''screen'', function() { return { scope: true, controller: function() { this.doSomethingScreeny = function() { alert("screeny!"); } } } }) .directive(''component'', function() { return { scope: true, controller: function($element) { this.componentFunction = function() { $element.controller(''screen'').doSomethingScreeny(); } } } }) .directive(''widget'', function() { return { scope: true, controller: function($scope, $element) { $scope.widgetFunction = function() { $element.controller(''component'').componentFunction(); } } } }) .controller(''MyCtrl'', function($scope) { $scope.name = ''Superhero''; })

<body ng-app="myApp"> <div ng-controller="MyCtrl"> <div screen> <div component> <div widget> <button ng-click="widgetFunction()">Woo Hoo</button> </div> </div> </div> </div> </body> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>

Si desea acceder a una función definida en el controlador de directivas de pantalla desde el controlador de directivas de componentes (no una función de enlace), puede usar $element.controller(''screen'').doSomethingScreeny() (de la directiva de componentes ).

JSFiddle

documentation angular:

  • controller(name) : recupera el controlador del elemento actual o su elemento primario. Por defecto recupera el controlador asociado con la directiva ngController . Si el name se proporciona como el nombre de la directiva camelCase, entonces se recuperará el controlador para esta directiva (por ejemplo, ''ngModel'' ).