Solución:
Hay varias formas de comunicarse entre controladores.
Probablemente el mejor sea compartir un servicio:
function FirstController(someDataService)
{
// use the data service, bind to template...
// or call methods on someDataService to send a request to server
}
function SecondController(someDataService)
{
// has a reference to the same instance of the service
// so if the service updates state for example, this controller knows about it
}
Otra forma es emitir un evento en el alcance:
function FirstController($scope)
{
$scope.$on('someEvent', function(event, args) {});
// another controller or even directive
}
function SecondController($scope)
{
$scope.$emit('someEvent', args);
}
En ambos casos, también puede comunicarse con cualquier directiva.
Vea este violín: http://jsfiddle.net/simpulton/XqDxG/
Vea también el siguiente video: Comunicación entre controladores
HTML:
<div ng-controller="ControllerZero">
<input ng-model="message" >
<button ng-click="handleClick(message);">LOG</button>
</div>
<div ng-controller="ControllerOne">
<input ng-model="message" >
</div>
<div ng-controller="ControllerTwo">
<input ng-model="message" >
</div>
javascript:
var myModule = angular.module('myModule', []);
myModule.factory('mySharedService', function($rootScope) {
var sharedService = {};
sharedService.message="";
sharedService.prepForBroadcast = function(msg) {
this.message = msg;
this.broadcastItem();
};
sharedService.broadcastItem = function() {
$rootScope.$broadcast('handleBroadcast');
};
return sharedService;
});
function ControllerZero($scope, sharedService) {
$scope.handleClick = function(msg) {
sharedService.prepForBroadcast(msg);
};
$scope.$on('handleBroadcast', function() {
$scope.message = sharedService.message;
});
}
function ControllerOne($scope, sharedService) {
$scope.$on('handleBroadcast', function() {
$scope.message="ONE: " + sharedService.message;
});
}
function ControllerTwo($scope, sharedService) {
$scope.$on('handleBroadcast', function() {
$scope.message="TWO: " + sharedService.message;
});
}
ControllerZero.$inject = ['$scope', 'mySharedService'];
ControllerOne.$inject = ['$scope', 'mySharedService'];
ControllerTwo.$inject = ['$scope', 'mySharedService'];
Si desea llamar a un controlador a otro, hay cuatro métodos disponibles
- $ rootScope. $ emit () y $ rootScope. $ broadcast ()
- Si el segundo controlador es secundario, puede utilizar la comunicación entre padres e hijos.
- Servicios de uso
- Tipo de truco: con la ayuda de angular.element ()
1. $ rootScope. $ Emit () y $ rootScope. $ Broadcast ()
El controlador y su alcance pueden destruirse, pero $ rootScope permanece en la aplicación, por eso estamos tomando $ rootScope porque $ rootScope es el padre de todos los alcances.
Si está comunicando de padre a hijo e incluso el niño quiere comunicarse con sus hermanos, puede usar $ broadcast
Si está realizando una comunicación de niño a padre, no hay hermanos involucrados, entonces puede usar $ rootScope. $ Emit
HTML
<body ng-app="myApp">
<div ng-controller="ParentCtrl" class="ng-scope">
// ParentCtrl
<div ng-controller="Sibling1" class="ng-scope">
// Sibling first controller
</div>
<div ng-controller="Sibling2" class="ng-scope">
// Sibling Second controller
<div ng-controller="Child" class="ng-scope">
// Child controller
</div>
</div>
</div>
</body>
Código Angularjs
var app = angular.module('myApp',[]);//We will use it throughout the example
app.controller('Child', function($rootScope) {
$rootScope.$emit('childEmit', 'Child calling parent');
$rootScope.$broadcast('siblingAndParent');
});
app.controller('Sibling1', function($rootScope) {
$rootScope.$on('childEmit', function(event, data) {
console.log(data + ' Inside Sibling one');
});
$rootScope.$on('siblingAndParent', function(event, data) {
console.log('broadcast from child in parent');
});
});
app.controller('Sibling2', function($rootScope) {
$rootScope.$on('childEmit', function(event, data) {
console.log(data + ' Inside Sibling two');
});
$rootScope.$on('siblingAndParent', function(event, data) {
console.log('broadcast from child in parent');
});
});
app.controller('ParentCtrl', function($rootScope) {
$rootScope.$on('childEmit', function(event, data) {
console.log(data + ' Inside parent controller');
});
$rootScope.$on('siblingAndParent', function(event, data) {
console.log('broadcast from child in parent');
});
});
En el código anterior, la consola de $ emit ‘childEmit’ no llamará a los hermanos menores internos y solo llamará al padre interno, donde $ broadcast también se llamará a los hermanos internos y al padre. Este es el lugar donde el rendimiento entra en acción. $ Emit es preferible, si está utilizando la comunicación de niño a padre porque omite algunos controles sucios.
2. Si el segundo controlador es un niño, puede utilizar la comunicación entre padres e hijos
Es uno de los mejores métodos, si quieres hacer comunicación entre padres e hijos donde el niño quiere comunicarse con padre inmediato entonces no necesitaría ningún tipo de $ broadcast o $ emit, pero si desea comunicarse de padres a hijos, debe usar el servicio o $ broadcast
Por ejemplo HTML: –
<div ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl">
</div>
</div>
Angularjs
app.controller('ParentCtrl', function($scope) {
$scope.value="Its parent";
});
app.controller('ChildCtrl', function($scope) {
console.log($scope.value);
});
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 principal.
3.Utilice los servicios
AngularJS admite los conceptos de “Separación de preocupaciones” utilizando arquitectura de servicios. Los servicios son funciones de JavaScript y son responsables de realizar tareas específicas, lo que los convierte en entidad individual cual es mantenible y comprobable.Servicios utilizados para inyectar usando el mecanismo de inyección de dependencia de Angularjs.
Código Angularjs:
app.service('communicate',function(){
this.communicateValue="Hello";
});
app.controller('ParentCtrl',function(communicate){//Dependency Injection
console.log(communicate.communicateValue+" Parent World");
});
app.controller('ChildCtrl',function(communicate){//Dependency Injection
console.log(communicate.communicateValue+" Child World");
});
Dará salida Hello Child World y Hello Parent World. Según los documentos de servicios de Angular Singletons: cada componente que depende de un servicio obtiene una referencia a la instancia única generada por la fábrica de servicios.
4.Tipo de truco: con la ayuda de angular.element ()
Este método obtiene scope () del elemento por su Id / unique class.angular.element () método devuelve elemento y scope () da $ scope variable de otra variable usando $ scope variable de un controlador dentro de otro no es una buena práctica.
HTML: –
<div id='parent' ng-controller="ParentCtrl">{{varParent}}
<span ng-click='getValueFromChild()'>Click to get ValueFormChild</span>
<div id='child' ng-controller="childCtrl">{{varChild}}
<span ng-click='getValueFromParent()'>Click to get ValueFormParent </span>
</div>
</div>
Angularjs: –
app.controller('ParentCtrl',function($scope){
$scope.varParent="Hello Parent";
$scope.getValueFromChild=function(){
var childScope=angular.element('#child').scope();
console.log(childScope.varChild);
}
});
app.controller('ChildCtrl',function($scope){
$scope.varChild="Hello Child";
$scope.getValueFromParent=function(){
var parentScope=angular.element('#parent').scope();
console.log(parentScope.varParent);
}
});
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 del niño y viceversa.