¿Es posible que un controlador use otro?
Por ejemplo:
Este documento HTML simplemente imprime un mensaje entregado por el MessageCtrl
controlador en el messageCtrl.js
archivo.
<html xmlns:ng="http://angularjs.org/">
<head>
<meta charset="utf-8" />
<title>Inter Controller Communication</title>
</head>
<body>
<div ng:controller="MessageCtrl">
<p>{{message}}</p>
</div>
<!-- Angular Scripts -->
<script src="http://code.angularjs.org/angular-0.9.19.js" ng:autobind></script>
<script src="js/messageCtrl.js" type="text/javascript"></script>
</body>
</html>
El archivo del controlador contiene el siguiente código:
function MessageCtrl()
{
this.message = function() {
return "The current date is: " + new Date().toString();
};
}
Que simplemente imprime la fecha actual;
Si tuviera que agregar otro controlador, DateCtrl
que devolvió la fecha en un formato específico MessageCtrl
, ¿cómo podría uno hacer esto? El marco DI parece estar preocupado XmlHttpRequests
y tener acceso a los servicios.
javascript
html
angularjs
BanksySan
fuente
fuente
Respuestas:
Hay varias formas de comunicarse entre los controladores.
El mejor probablemente sea compartir un servicio:
Otra forma es emitir un evento en el alcance:
En ambos casos, también puede comunicarse con cualquier directiva.
fuente
Vea este violín: http://jsfiddle.net/simpulton/XqDxG/
También vea el siguiente video: Comunicación entre controladores
HTML:
javascript:
fuente
Si desea llamar un controlador a otro, hay cuatro métodos disponibles
El controlador y su alcance pueden destruirse, pero $ rootScope permanece en toda la aplicación, por eso estamos tomando $ rootScope porque $ rootScope es el padre de todos los ámbitos.
Si está realizando una comunicación de padre a hijo e incluso el niño quiere comunicarse con sus hermanos, puede usar $ broadcast
Si está realizando una comunicación de hijo a padre, no se invocan hermanos, entonces puede usar $ rootScope. $ Emit
HTML
Código Angularjs
En la consola de código anterior de $ emit, 'childEmit' no llamará dentro de los hermanos menores y solo llamará dentro de los padres, donde $ broadcast también se llamará dentro de los hermanos y los padres. Este es el lugar donde el rendimiento entra en acción. $ Emit es preferible, si está utilizando comunicación de niño a padre porque omite algunos cheques sucios.
Es uno de los mejores métodos, si desea comunicarse con los padres de los niños donde el niño quiere comunicarse con los padres inmediatos, entonces no necesitaría ningún tipo de $ broadcast o $ emit, pero si desea comunicarse de padres a hijos, entonces debe use el servicio o $ broadcast
Por ejemplo HTML: -
Angularjs
Siempre que esté utilizando la comunicación de niño a padre, Angularjs buscará una variable dentro del niño. Si no está presente en el interior, elegirá ver los valores dentro del controlador padre.
AngularJS admite los conceptos de "separación de preocupaciones" utilizando la arquitectura de servicios. Los servicios son funciones de JavaScript y son responsables de realizar solo tareas específicas. Esto los convierte en una entidad individual que es mantenible y comprobable servicios solían inyectarse usando el mecanismo de inyección de dependencia de Angularjs.
Código Angularjs:
Dará salida Hello Child World y Hello Parent World. De acuerdo con documentos angulares de servicios Singletons: cada componente dependiente de un servicio obtiene una referencia a la instancia única generada por la fábrica de servicios .
Este método obtiene el alcance () del elemento por su Id / unique class.angular.element () el método devuelve el elemento y el alcance () da la variable $ scope de otra variable usando la variable $ scope de un controlador dentro de otro no es una buena práctica.
HTML: -
Angularjs: -
En el código anterior, los controladores muestran su propio valor en Html y cuando haga clic en el texto obtendrá los valores en la consola en consecuencia. Si hace clic en el intervalo de los controladores principales, el navegador consolará el valor de child y viceversa.
fuente
Aquí hay un ejemplo de una página de dos controladores que comparten datos de servicio:
También aquí: https://gist.github.com/3595424
fuente
theService
actualizathing.x
, entonces ese cambio se propaga automáticamente a <input> s enFirstCtrl
ySecondCtrl
, ¿verdad? Y también se puede cambiarthing.x
directamente a través de cualquiera de los dos <input> s (¿verdad?).Si está buscando emitir y transmitir eventos para compartir datos o funciones de llamada entre los controladores , mire este enlace : y verifique la respuesta por
zbynour
(respuesta con el máximo de votos). ¡Estoy citando su respuesta!Si el alcance de firstCtrl es padre del alcance de secondCtrl, su código debería funcionar reemplazando $ emit por $ broadcast en firstCtrl:
En caso de que no haya una relación padre-hijo entre sus ámbitos, puede inyectar $ rootScope en el controlador y transmitir el evento a todos los ámbitos secundarios (es decir, también secondCtrl).
Finalmente, cuando necesite despachar el evento desde el controlador secundario a los ámbitos hacia arriba, puede usar $ scope. $ Emit. Si el alcance de firstCtrl es padre del alcance de secondCtrl:
fuente
Dos violines más: (enfoque sin servicio)
1) Para el controlador
$scope
padre -hijo: uso del controlador padre para emitir / transmitir eventos. http://jsfiddle.net/laan_sachin/jnj6y/2) Uso a
$rootScope
través de controladores no relacionados. http://jsfiddle.net/VxafF/fuente
En realidad, el uso de emitir y emitir es ineficiente porque el evento sube y baja en la jerarquía del alcance, lo que puede degradarse fácilmente en una botella de rendimiento para una aplicación compleja.
Sugeriría usar un servicio. Así es como lo implementé recientemente en uno de mis proyectos: https://gist.github.com/3384419 .
Idea básica: registrar un bus pub-sub / event como servicio. Luego inyecte ese bus de eventos donde necesite suscribirse o publicar eventos / temas.
fuente
También sé de esta manera.
Pero no lo uso demasiado, porque no me gusta usar selectores jQuery en código angular.
fuente
Hay un método que no depende de los servicios,
$broadcast
o$emit
. No es adecuado en todos los casos, pero si tiene 2 controladores relacionados que pueden resumirse en directivas, puede usar larequire
opción en la definición de directiva. Es muy probable que así se comuniquen ngModel y ngForm. Puede usar esto para comunicarse entre controladores de directivas que están anidadas o en el mismo elemento.Para una situación padre / hijo, el uso sería el siguiente:
Y los puntos principales para que funcione: en la directiva principal, con los métodos que se deben llamar, debe definirlos en
this
(no en$scope
):En la definición de la directiva secundaria, puede usar la
require
opción para que el controlador principal pase a la función de enlace (para que luego pueda llamar a las funciones desde lascope
directiva secundaria.Lo anterior se puede ver en http://plnkr.co/edit/poeq460VmQER8Gl9w8Oz?p=preview
Una directiva entre hermanos se usa de manera similar, pero ambas directivas sobre el mismo elemento:
Usado al crear un método en
directive1
:Y en directive2 esto se puede llamar mediante el uso de la
require
opción que da como resultado que el siblingController se pase a la función de enlace:Esto se puede ver en http://plnkr.co/edit/MUD2snf9zvadfnDXq85w?p=preview .
Los usos de esto?
Parent: Cualquier caso en el que los elementos secundarios necesitan "registrarse" con un padre. Al igual que la relación entre ngModel y ngForm. Estos pueden agregar cierto comportamiento que puede afectar a los modelos. Es posible que también tenga algo basado exclusivamente en DOM, donde un elemento padre necesita administrar las posiciones de ciertos niños, por ejemplo, administrar o reaccionar al desplazamiento.
Hermano: permitir que una directiva modifique su comportamiento. ngModel es el caso clásico, para agregar analizadores / validación al uso de ngModel en las entradas.
fuente
No sé si esto está fuera de los estándares, pero si tiene todos sus controladores en el mismo archivo, puede hacer algo como esto:
Como puede ver los indicadores Ctrl está llamando a las funciones updateChart de los otros dos controladores al llamar a updateCharts.
fuente
Puede inyectar el servicio '$ controller' en su controlador principal (MessageCtrl) y luego instanciar / inyectar el controlador secundario (DateCtrl) usando:
$scope.childController = $controller('childController', { $scope: $scope.$new() });
Ahora puede acceder a los datos de su controlador secundario llamando a sus métodos, ya que es un servicio.
Avísame si hay algún problema.
fuente
El siguiente es un
publish-subscribe
enfoque que es independiente de Angular JS.Controlador de parámetros de búsqueda
Controlador de opciones de búsqueda
Administrador de evento
Global
fuente
En angular 1.5 esto se puede lograr haciendo lo siguiente:
Este es el componente principal. En esto, he creado una función que empuja a otro objeto en mi
productForms
matriz, nota: este es solo mi ejemplo, esta función puede ser cualquier cosa realmente.Ahora podemos crear otro componente que haga uso de
require
:Aquí, el componente secundario está creando una referencia a la función del componente primario
addNewForm
que luego puede vincularse al HTML y llamarse como cualquier otra función.fuente