$on i $ broadcast in angular
Mam footerController i codeScannerController z różnymi widokami.
angular.module('myApp').controller('footerController', ["$scope", function($scope) {}]);
angular.module('myApp').controller('codeScannerController', ["$scope", function($scope) {
console.log("start");
$scope.startScanner = function(){...
Kiedy klikam na <li>
w stopce.html powinienem pobrać to zdarzenie w codeScannerController.
<li class="button" ng-click="startScanner()">3</li>
Myślę, że można to zrealizować za pomocą $on
i $broadcast
, ale nie wiem jak i nigdzie nie mogę znaleźć przykładów.
4 answers
Jeśli chcesz $broadcast
Użyj $rootScope
:
$scope.startScanner = function() {
$rootScope.$broadcast('scanner-started');
}
A następnie, aby otrzymać, użyj $scope
swojego kontrolera:
$scope.$on('scanner-started', function(event, args) {
// do what you want to do
});
Jeśli chcesz możesz przekazać argumenty kiedy $broadcast
:
$rootScope.$broadcast('scanner-started', { any: {} });
A następnie otrzymać je:
$scope.$on('scanner-started', function(event, args) {
var anyThing = args.any;
// do what you want to do
});
Dokumentacja w Scope docs.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-23 14:11:42
Po pierwsze, Krótki opis $on()
, $broadcast()
oraz $emit()
:
-
.$on(name, listener)
- nasłuchuje określonego zdarzenia przez danyname
-
.$broadcast(name, args)
- transmitować wydarzenie przez$scope
wszystkich dzieci -
.$emit(name, args)
- emituje Zdarzenie w hierarchii {[8] } do wszystkich rodziców, w tym$rootScope
Na podstawie następującego kodu HTML (zobacz pełny przykład tutaj):
<div ng-controller="Controller1">
<button ng-click="broadcast()">Broadcast 1</button>
<button ng-click="emit()">Emit 1</button>
</div>
<div ng-controller="Controller2">
<button ng-click="broadcast()">Broadcast 2</button>
<button ng-click="emit()">Emit 2</button>
<div ng-controller="Controller3">
<button ng-click="broadcast()">Broadcast 3</button>
<button ng-click="emit()">Emit 3</button>
<br>
<button ng-click="broadcastRoot()">Broadcast Root</button>
<button ng-click="emitRoot()">Emit Root</button>
</div>
</div>
Wywołane zdarzenia przejdą $scopes
jako następuje:
- Broadcast 1 - będzie widoczny tylko przez kontroler 1
$scope
- Emit 1 - będzie widoczny przez kontroler 1
$scope
wtedy$rootScope
- Broadcast 2 - będzie widoczny przez kontroler 2
$scope
następnie kontroler 3$scope
- Emit 2 - będzie widoczny przez kontroler 2
$scope
Następnie$rootScope
- Broadcast 3 - będzie widoczny tylko przez kontroler 3
$scope
- Emit 3 - będzie widoczny przez kontroler 3
$scope
, Kontroler 2$scope
Następnie$rootScope
- Broadcast Root-Will być widziane przez
$rootScope
i$scope
wszystkich kontrolerów (1, 2, 3) - Emit Root - będzie widoczny tylko przez
$rootScope
JavaScript, aby wyzwalać zdarzenia (ponownie możesz zobaczyć działający przykład tutaj):
app.controller('Controller1', ['$scope', '$rootScope', function($scope, $rootScope){
$scope.broadcastAndEmit = function(){
// This will be seen by Controller 1 $scope and all children $scopes
$scope.$broadcast('eventX', {data: '$scope.broadcast'});
// Because this event is fired as an emit (goes up) on the $rootScope,
// only the $rootScope will see it
$rootScope.$emit('eventX', {data: '$rootScope.emit'});
};
$scope.emit = function(){
// Controller 1 $scope, and all parent $scopes (including $rootScope)
// will see this event
$scope.$emit('eventX', {data: '$scope.emit'});
};
$scope.$on('eventX', function(ev, args){
console.log('eventX found on Controller1 $scope');
});
$rootScope.$on('eventX', function(ev, args){
console.log('eventX found on $rootScope');
});
}]);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-24 09:51:48
Należy wiedzieć, że prefix $ odnosi się do metody kątowej, prefix $$ odnosi się do metod kątowych, których należy unikać.
Poniżej znajduje się przykładowy szablon i jego Kontrolery, zbadamy, w jaki sposób $broadcast/$on może pomóc nam osiągnąć to, czego chcemy.
<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>
Kontrolerami są
app.controller('FirstCtrl', function($scope){
$scope.register = function(){
}
});
app.controller('SecondCtrl', function($scope){
});
Moje pytanie do ciebie brzmi jak przekazać nazwę do drugiego kontrolera, gdy użytkownik kliknie zarejestruj? Możesz wymyślić wiele rozwiązań, ale tego, którego użyjemy używa $broadcast i $on.
$broadcast vs $emit
Czego powinniśmy użyć? $broadcast skieruje się w dół do wszystkich potomnych elementów dom, a $emit skieruje się w przeciwnym kierunku do wszystkich przodkowych elementów dom.
Najlepszym sposobem na uniknięcie decyzji pomiędzy $emit lub $broadcast jest kanał z $ rootScope i używanie $ broadcast do wszystkich jego dzieci. Co znacznie ułatwia sprawę, ponieważ nasze elementy dom są rodzeństwem.
Dodawanie $rootScope and lets $broadcast
app.controller('FirstCtrl', function($rootScope, $scope){
$scope.register = function(){
$rootScope.$broadcast('BOOM!', $scope.name)
}
});
Uwaga dodaliśmy $rootScope i teraz używamy $broadcast (broadcastName, arguments). Dla broadcastName, chcemy nadać mu unikalną nazwę, abyśmy mogli złapać tę nazwę w naszym secondCtrl. Wybrałem BOOM! dla Zabawy. Drugi argument 'arguments' pozwala nam przekazywać wartości do słuchaczy.
Odbieranie naszej transmisji
W naszym drugim kontrolerze musimy ustawić kod do odsłuchu naszej transmisji
app.controller('SecondCtrl', function($scope){
$scope.$on('BOOM!', function(events, args){
console.log(args);
$scope.name = args; //now we've registered!
})
});
To naprawdę to proste. Przykład Na Żywo
Inne sposoby osiągnięcia podobnych wyników
Staraj się unikać używania tego zestawu metod, ponieważ nie jest ani wydajny, ani łatwy w utrzymaniu, ale jest to prosty sposób na naprawienie problemów, które możesz mieć.
Zazwyczaj możesz zrobić to samo, korzystając z usługi lub upraszczając Kontrolery. Nie będziemy omawiać tego szczegółowo, ale pomyślałem, że wspomnę o tym dla kompletności.
Na koniec należy pamiętać o naprawdę użytecznej transmisji do listen to jest '$ destroy ' ponownie widać $ oznacza, że jest to metoda lub obiekt utworzony przez kody dostawcy. Tak czy inaczej $destroy jest nadawany, gdy kontroler zostanie zniszczony, możesz posłuchać tego, aby wiedzieć, kiedy kontroler zostanie usunięty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-01 23:58:19
//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();
};
}); }());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-13 21:06:46