Ho un footerController e un codeScannerController con diverse viste.
angular.module('myApp').controller('footerController', ["$scope", function($scope) {}]);
angular.module('myApp').controller('codeScannerController', ["$scope", function($scope) {
console.log("start");
$scope.startScanner = function(){...
Quando clicco su un <li>
in footer.html dovrei ottenere questo evento in codeScannerController.
<li class="button" ng-click="startScanner()">3</li>
Penso che possa essere realizzato con $on
e $broadcast
, ma non so come e non riesco a trovare esempi da nessuna parte.
Se volete $broadcast
usate il $rootScope
:
$scope.startScanner = function() {
$rootScope.$broadcast('scanner-started');
}
E poi per ricevere, usa il $scope
del tuo controller:
$scope.$on('scanner-started', function(event, args) {
// do what you want to do
});
Se vuoi, puoi passare degli argomenti quando fai $broadcast
:
$rootScope.$broadcast('scanner-started', { any: {} });
E poi riceverli:
$scope.$on('scanner-started', function(event, args) {
var anyThing = args.any;
// do what you want to do
});
Documentazione per questo all'interno della Scope docs.
Una cosa che dovresti sapere è il prefisso $ si riferisce a un metodo Angular, i prefissi $$ si riferiscono a metodi angolari che dovresti evitare di usare.
Di seguito è riportato un template di esempio e i suoi controller, esploreremo come $broadcast/$on può aiutarci a raggiungere ciò che vogliamo.
<div ng-controller="FirstCtrl">
<input ng-model="name"/>
<button ng-click="register()">Register </button>
</div>
<div ng-controller="SecondCtrl">
Registered Name: <input ng-model="name"/>
</div>
I controllori sono
app.controller('FirstCtrl', function($scope){
$scope.register = function(){
}
});
app.controller('SecondCtrl', function($scope){
});
La mia domanda è come si fa a passare il nome al secondo controllore quando un utente fa clic su register? Potreste trovare diverse soluzioni, ma quella che useremo è usare $broadcast e $on.
$broadcast vs $emit
Quale dovremmo usare? $broadcast canalizzerà verso il basso tutti gli elementi dom figli e $emit canalizzerà nella direzione opposta tutti gli elementi dom antenati.
Il modo migliore per evitare di decidere tra $emit o $broadcast è di canalizzare da $rootScope e usare $broadcast a tutti i suoi figli. Il che rende il nostro caso molto più semplice dato che i nostri elementi dom sono fratelli.
Aggiungi $rootScope e lascia $broadcast
app.controller('FirstCtrl', function($rootScope, $scope){
$scope.register = function(){
$rootScope.$broadcast('BOOM!', $scope.name)
}
});
Notate che abbiamo aggiunto $rootScope e ora stiamo usando $broadcast(broadcastName, arguments). Per broadcastName, vogliamo dargli un nome unico in modo da poter catturare quel nome nel nostro secondCtrl. Ho scelto BOOM! solo per divertimento. Il secondo argomento 'arguments'ci permette di passare dei valori agli ascoltatori.
Ricevere la nostra trasmissione
Nel nostro secondo controller, dobbiamo impostare il codice per ascoltare la nostra trasmissione
app.controller('SecondCtrl', function($scope){
$scope.$on('BOOM!', function(events, args){
console.log(args);
$scope.name = args; //now we've registered!
})
});
È davvero così semplice. Esempio dal vivo
Altri modi per ottenere risultati simili
Cercate di evitare di usare questa serie di metodi perché non è né efficiente né facile da mantenere, ma è un modo semplice per risolvere i problemi che potreste avere.
Di solito puoi fare la stessa cosa usando un servizio o semplificando i tuoi controller. Non ne parleremo in dettaglio ma ho pensato di menzionarlo per completezza.
Infine, tenete a mente una trasmissione davvero utile da ascoltare è '$destroy' di nuovo potete vedere il $ significa che è un metodo o un oggetto creato dai codici del venditore. Comunque $destroy viene trasmesso quando un controller viene distrutto, potresti voler ascoltare questo per sapere quando il tuo controller viene rimosso.
//Your broadcast in service
(function () {
angular.module('appModule').factory('AppService', function ($rootScope, $timeout) {
function refreshData() {
$timeout(function() {
$rootScope.$broadcast('refreshData');
}, 0, true);
}
return {
RefreshData: refreshData
};
}); }());
//Controller Implementation
(function () {
angular.module('appModule').controller('AppController', function ($rootScope, $scope, $timeout, AppService) {
//Removes Listeners before adding them
//This line will solve the problem for multiple broadcast call
$scope.$$listeners['refreshData'] = [];
$scope.$on('refreshData', function() {
$scope.showData();
});
$scope.onSaveDataComplete = function() {
AppService.RefreshData();
};
}); }());