AngularJS
Wydarzenia
Szukaj…
Parametry
Parametry | Typy wartości |
---|---|
zdarzenie | Obiekt {name: "eventName", targetScope: Scope, defaultPrevented: false, currentScope: ChildScope} |
args | dane, które zostały przekazane wraz z wykonaniem zdarzenia |
Korzystanie z systemu zdarzeń kątowych
$ scope. $ emit
Użycie $scope.$emit
wywoła nazwę zdarzenia w górę poprzez hierarchię zasięgu i powiadomi $scope
. Cykl życia zdarzenia rozpoczyna się od zakresu, w którym $emit
.
Roboczy szkielet:
$ scope. $ broadcast
Użycie $scope.$broadcast
wywoła zdarzenie w dół $scope
. Możemy słuchać tych wydarzeń za pomocą $scope.$on
Roboczy szkielet:
Składnia:
// firing an event upwards
$scope.$emit('myCustomEvent', 'Data to send');
// firing an event downwards
$scope.$broadcast('myCustomEvent', {
someProp: 'some value'
});
// listen for the event in the relevant $scope
$scope.$on('myCustomEvent', function (event, data) {
console.log(data); // 'Data from the event'
});
Zamiast $scope
możesz użyć $rootScope
, w takim przypadku twoje zdarzenie będzie dostępne na wszystkich kontrolerach niezależnie od tego zakresu kontrolerów
Wyczyść zarejestrowane zdarzenie w AngularJS
Powodem wyczyszczenia zarejestrowanych zdarzeń, ponieważ nawet kontroler został zniszczony, obsługa zarejestrowanych zdarzeń jest nadal aktywna. Na pewno kod będzie działał jak nieoczekiwany.
// firing an event upwards
$rootScope.$emit('myEvent', 'Data to send');
// listening an event
var listenerEventHandler = $rootScope.$on('myEvent', function(){
//handle code
});
$scope.$on('$destroy', function() {
listenerEventHandler();
});
Zastosowania i znaczenie
Te zdarzenia mogą służyć do komunikacji między 2 lub więcej kontrolerami.
$emit
emit wywołuje zdarzenie w górę poprzez hierarchię zasięgu, a $broadcast
wywołuje zdarzenie w dół do wszystkich zakresów potomnych. Zostało to tutaj pięknie wyjaśnione.
Podczas komunikacji między kontrolerami mogą istnieć dwa rodzaje scenariuszy:
- Gdy kontrolery mają relację rodzic-dziecko. (w takich scenariuszach możemy głównie użyć
$scope
)
- Gdy kontrolery nie są od siebie niezależne i muszą być informowane o swoich działaniach. (możemy użyć
$rootScope
w takich scenariuszach)
np .: w przypadku dowolnej witryny e-commerce załóżmy, że mamy ProductListController
(który kontroluje stronę z listą produktów po kliknięciu dowolnej marki produktu) i CartController
(do zarządzania produktami w koszyku). Teraz, kiedy klikamy przycisk Dodaj do koszyka , należy o tym również poinformować CartController
, aby mógł odzwierciedlić liczbę / szczegóły nowego koszyka na pasku nawigacyjnym witryny. Można to osiągnąć za pomocą $rootScope
.
Z $scope.$emit
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<script>
var app = angular.module('app', []);
app.controller("FirstController", function ($scope) {
$scope.$on('eventName', function (event, args) {
$scope.message = args.message;
});
});
app.controller("SecondController", function ($scope) {
$scope.handleClick = function (msg) {
$scope.$emit('eventName', {message: msg});
};
});
</script>
</head>
<body ng-app="app">
<div ng-controller="FirstController" style="border:2px ;padding:5px;">
<h1>Parent Controller</h1>
<p>Emit Message : {{message}}</p>
<br />
<div ng-controller="SecondController" style="border:2px;padding:5px;">
<h1>Child Controller</h1>
<input ng-model="msg">
<button ng-click="handleClick(msg);">Emit</button>
</div>
</div>
</body>
</html>
Z $scope.$broadcast
:
<html>
<head>
<title>Broadcasting</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<script>
var app = angular.module('app', []);
app.controller("FirstController", function ($scope) {
$scope.handleClick = function (msg) {
$scope.$broadcast('eventName', {message: msg});
};
});
app.controller("SecondController", function ($scope) {
$scope.$on('eventName', function (event, args) {
$scope.message = args.message;
});
});
</script>
</head>
<body ng-app="app">
<div ng-controller="FirstController" style="border:2px solid ; padding:5px;">
<h1>Parent Controller</h1>
<input ng-model="msg">
<button ng-click="handleClick(msg);">Broadcast</button>
<br /><br />
<div ng-controller="SecondController" style="border:2px solid ;padding:5px;">
<h1>Child Controller</h1>
<p>Broadcast Message : {{message}}</p>
</div>
</div>
</body>
</html>
Zawsze wyrejestruj $ rootScope. $ Na słuchaczach zdarzenia event $ scope
$ rootScope. $ na słuchaczach pozostanie w pamięci, jeśli przejdziesz do innego kontrolera. Spowoduje to wyciek pamięci, jeśli kontroler wyłączy się z zakresu.
Nie rób
angular.module('app').controller('badExampleController', badExample);
badExample.$inject = ['$scope', '$rootScope'];
function badExample($scope, $rootScope) {
$rootScope.$on('post:created', function postCreated(event, data) {});
}
Robić
angular.module('app').controller('goodExampleController', goodExample);
goodExample.$inject = ['$scope', '$rootScope'];
function goodExample($scope, $rootScope) {
var deregister = $rootScope.$on('post:created', function postCreated(event, data) {});
$scope.$on('$destroy', function destroyScope() {
deregister();
});
}