otro llamar funcion ejemplos directivas desde crear controlador javascript jquery angularjs angularjs-directive

javascript - ejemplos - llamar funcion angular desde html



Método de llamada en controlador de directivas desde otro controlador (4)

Tengo una directiva que tiene su propio controlador. Vea el siguiente código:

var popdown = angular.module(''xModules'',[]); popdown.directive(''popdown'', function () { var PopdownController = function ($scope) { this.scope = $scope; } PopdownController.prototype = { show:function (message, type) { this.scope.message = message; this.scope.type = type; }, hide:function () { this.scope.message = ''''; this.scope.type = ''''; } } var linkFn = function (scope, lElement, attrs, controller) { }; return { controller: PopdownController, link: linkFn, replace: true, templateUrl: ''./partials/modules/popdown.html'' } });

Esto debe ser un sistema de notificación de errores / notificaciones / advertencias. Lo que quiero hacer es usar otro controlador (no uno de directivas) para llamar a la función show en este controlador. Y cuando lo haga, también me gustaría que mi función de enlace detecte que algunas propiedades cambiaron y realizar algunas animaciones.

Aquí hay un código para ejemplificar lo que estoy pidiendo:

var app = angular.module(''app'', [''RestService'']); app.controller(''IndexController'', function($scope, RestService) { var result = RestService.query(); if(result.error) { popdown.notify(error.message, ''error''); } });

Por lo tanto, cuando llame a show en el controlador de directivas popdown , la función de enlace también se debe activar y realizar una animación. ¿Cómo podría lograr eso?


Esta es una pregunta interesante, y comencé a pensar cómo implementaría algo como esto.

Se me ocurrió esto (violín) ;

Básicamente, en lugar de tratar de llamar a una directiva de un controlador, creé un módulo para albergar toda la lógica emergente:

var PopdownModule = angular.module(''Popdown'', []);

Puse dos cosas en el módulo, una factory para la API que se puede inyectar en cualquier lugar, y la directive para definir el comportamiento del elemento real de la ventana emergente:

La fábrica solo define un par de funciones de success y error y realiza un seguimiento de un par de variables:

PopdownModule.factory(''PopdownAPI'', function() { return { status: null, message: null, success: function(msg) { this.status = ''success''; this.message = msg; }, error: function(msg) { this.status = ''error''; this.message = msg; }, clear: function() { this.status = null; this.message = null; } } });

La directiva obtiene la API inyectada en su controlador, y mira la API para ver los cambios (estoy usando bootstrap css por conveniencia):

PopdownModule.directive(''popdown'', function() { return { restrict: ''E'', scope: {}, replace: true, controller: function($scope, PopdownAPI) { $scope.show = false; $scope.api = PopdownAPI; $scope.$watch(''api.status'', toggledisplay) $scope.$watch(''api.message'', toggledisplay) $scope.hide = function() { $scope.show = false; $scope.api.clear(); }; function toggledisplay() { $scope.show = !!($scope.api.status && $scope.api.message); } }, template: ''<div class="alert alert-{{api.status}}" ng-show="show">'' + '' <button type="button" class="close" ng-click="hide()">&times;</button>'' + '' {{api.message}}'' + ''</div>'' } })

Luego defino un módulo de app que depende de Popdown :

var app = angular.module(''app'', [''Popdown'']); app.controller(''main'', function($scope, PopdownAPI) { $scope.success = function(msg) { PopdownAPI.success(msg); } $scope.error = function(msg) { PopdownAPI.error(msg); } });

Y el HTML se ve así:

<html ng-app="app"> <body ng-controller="main"> <popdown></popdown> <a class="btn" ng-click="success(''I am a success!'')">Succeed</a> <a class="btn" ng-click="error(''Alas, I am a failure!'')">Fail</a> </body> </html>

No estoy seguro de si es completamente ideal, pero parecía una forma razonable de establecer una comunicación con una directiva emergente global.

De nuevo, como referencia, el violín .


También podría exponer el controlador de la directiva al ámbito principal, como lo hace ngForm con el atributo name : http://docs.angularjs.org/api/ng.directive:ngForm

Aquí puede encontrar un ejemplo muy básico de cómo se puede lograr http://plnkr.co/edit/Ps8OXrfpnePFvvdFgYJf?p=preview

En este ejemplo, tengo myDirective con un controlador dedicado con $clear method (una especie de API pública muy simple para la directiva). Puedo publicar este controlador en el alcance principal y usar llamar a este método fuera de la directiva.


También puede usar eventos para activar Popdown.

Aquí hay un violín basado en la solución de satchmorun. Se prescinde de PopdownAPI, y el controlador de nivel superior en lugar de $broadcast s ''éxito'' y ''error'' eventos en la cadena de alcance:

$scope.success = function(msg) { $scope.$broadcast(''success'', msg); }; $scope.error = function(msg) { $scope.$broadcast(''error'', msg); };

El módulo Popdown luego registra las funciones del manejador para estos eventos, por ejemplo:

$scope.$on(''success'', function(event, msg) { $scope.status = ''success''; $scope.message = msg; $scope.toggleDisplay(); });

Esto funciona, al menos, y me parece una solución muy bien disociada. Dejaré que otros hablen si esto se considera una mala práctica por alguna razón.


Tengo una solución mucho mejor.

aquí está mi directiva, he insertado en referencia de objeto en directiva y lo he extendido al agregar función de invocación en código de directiva.

app.directive(''myDirective'', function () { return { restrict: ''E'', scope: { /*The object that passed from the cntroller*/ objectToInject: ''='', }, templateUrl: ''templates/myTemplate.html'', link: function ($scope, element, attrs) { /*This method will be called whet the ''objectToInject'' value is changes*/ $scope.$watch(''objectToInject'', function (value) { /*Checking if the given value is not undefined*/ if(value){ $scope.Obj = value; /*Injecting the Method*/ $scope.Obj.invoke = function(){ //Do something } } }); } }; });

Declarar la directiva en el HTML con un parámetro:

<my-directive object-to-inject="injectedObject"></ my-directive>

mi controlador:

app.controller("myController", [''$scope'', function ($scope) { // object must be empty initialize,so it can be appended $scope.injectedObject = {}; // now i can directly calling invoke function from here $scope.injectedObject.invoke(); }];