niedziela, 7 października 2012

[HTML|JS|CSS] AngularJS: Event Handlers

Zdarzenia możemy obsługiwać zarówno czystym JavaScriptem, jak i przyjazną biblioteką jQuery, Dlaczego więc korzystać z Angulara ? Ponieważ kilka rzeczy otrzymujemy za darmo. Po pierwsze w sposób deklaratywny w widoku możemy wpisać wyrażenia, które będą ewaluowane, gdy dane zdarzenie będzie miało miejsce. Można też oczywiście przekazać callback, który będzie odpowiednią funkcją z kontrolera. Przykład poniżej.

<!doctype html>
<html ng-app>
<head>
<meta charset="utf-8">
 <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
 <script src="scripts/myscript.js"></script>
</head>
<body ng-controller="eventsController"> 
 <div ng-click="counter = counter + 1">click test</div>
 <div ng-click="clicks()">display</div>
 <div ng-mousemove="mouse = mouse + 1"
  ng-mouseout ="display()">here move mouse</div>
</body>
</html>

Cały kod po stronie kontrolera to inicjalizacja zmiennych i deklaracja funkcji.

function eventsController($scope){
 $scope.counter = 0;
 $scope.mouse = 0;
 $scope.clicks = function(e){
  console.log('clicks  ' + $scope.counter);
 }
 $scope.display = function(e){
  console.log('mouse moves ' + $scope.mouse);
  $scope.mouse = 0;
 }
}

Zdarzenia AngularJS wywoływane są w kontekście danego scope, dlatego jeśli w danym zdarzeniu chcemy modyfikować model DOM, to zostanie on automatycznie odświeżony. Korzystając z innych bibliotek w połączeniu z Angularem nie mamy tego konfortu i należy wykorzystywać instrukcję $scope.$apply do automatycznego odświeżenia UI. Poniżej porównanie równoważnych funkcjonalnie handlerów w jQuery i AngularJS.

<body ng-controller="eventsController"> 
 <div ng-click="add()">add element </div>
 <div id="add">add element (bind) </div>
 <ul>
  <li ng-repeat="n in numbers">{{n}}</li>
 </ul>
</body>

function eventsController($scope){
 $scope.numbers = [1,2];
 $scope.add = function(e){
  $scope.numbers.push($scope.counter);
 }

 $('#add').click(function(e){
  $scope.$apply($scope.numbers.push($scope.counter));
 })
}

Ostatnią przydatną funkcjonalnością dotyczącą zdarzeń jest możliwość ich propagacji w górę lub w dół drzewa DOM. Służą do tego odpowiednio funkcje $emit oraz $broadcast. 

<div ng-click="$broadcast('myevent')">
 Click to broadcast down, emittedEvents: {{outerEvents}}
 <div ng-controller="innerController">
  <div ng-click="$emit('myevent2')">
   Emit up, broadcastedEvents: {{innerEvents}}
  </div>
 </div>
</div>

Obsługa w kontrolerze wykonywana jest dzięki instrukcji $on.

function eventsController($scope){
 $scope.outerEvents = 0;
 $scope.$on('myevent2', function() {
  $scope.outerEvents++;
 });
}

function innerController($scope){
  $scope.innerEvents = 0;
  $scope.$on('myevent', function() {
  $scope.innerEvents++;
 });
}

Brak komentarzy:

Prześlij komentarz