W tym wpisie zostaną omówione podstawowe dyrektywy, których jeszcze nie używaliśmy podczas nauki omawianego frameworka. We wcześniejszych materiałach korzystaliśmy z kilku dyrektyw wbudowanych w AngularJS, były to: ng-app, ng-controller, ng-repeat, ng-click, ng-model. Napisana przez nas aplikacja wyglądem będzie przypominała te z wcześniejszych wpisów, jednak tym razem pokażę użycie nowych dyrektyw.
Dyrektywy
Ng-bind
Dyrektywa ta odpowiada za wiązanie danych, często jest zastępowana przez interpolację, czyli parę {{ }} np. {{ $ctrl.name }}. Zaletą stosowania tej dyrektywy jest pozbycie się problemu występującego podczas ładowania strony, kiedy to zamiast odpowiednich danych na stronie wyświetlane są klamerki wraz z wyrażeniami np. {{ $ctrl.name }}.
<h1 ng-bind="$ctrl.name"></h1>Ng-cloak
Umożliwia osiągnięcie podobnego efektu jak dzięki dyrektywy ng-bind podczas ładowania strony, gdy korzystamy z interpolacji (klamerek {{}}). Ważne jest aby dodać kod css, bez tego nie zobaczymy oczekiwanego rezultatu. Działa na elemencie do którego została dodana oraz na jego dzieciach. Można ją dodać do znacznika body, tak aby cała aplikacja z niej korzystała.
Klasa css
[ng\:cloak], [ng-cloak], .ng-cloak { display: none !important; }Kod JS
<h2 ng-cloak>{{$ctrl.ngCloak}}</h2>Ng-bind-html
To rozszerzona dyrektywa ng-bind, która pozwala programiście na wstrzykiwanie kodu HTML do danego elementu. Musimy jednak pamiętać, aby przed jej użyciem dodać do aplikacji moduł angularowy ngSanitize.
To kolejna dyrektywa umożliwiająca wstrzykiwanie kodu html do elementów.
<span ng-bind-html="$ctrl.bindHTML"></span>Ng-change
Odpowiada za wykonanie określonej operacji po dokonaniu zmiany w polu input. Reaguje na każdą zmianę w tym także usunięcie znaku.
<input type="text" ng-model="$ctrl.inputChange" ng-change="$ctrl.change()">Ng-class
Daje nam możliwość dodawania klas do elementów pod określonymi warunkami, jeżeli warunek jest spełniony nowa klasa zostanie dodana. Możemy jednocześnie dodawać wiele klas.
<span ng-class="{ 'ng-class-true': $ctrl.ngClass, 'ng-class-false': !$ctrl.ngClass }">Dyrektywa ngClass</span> <input type="checkbox" ng-model="$ctrl.ngClass">Ng-repeat
Z dyrektywy tej już korzystaliśmy niejednokrotnie, jednak nie wspominałem jeszcze o jej wszystkich możliwościach. Iterując po kolekcji mamy dostęp do specjalnych adekwatności:
- $index – to numer elementu w zbiorze, zaczyna się od 0 i kończy na n-1,
- $first – zwraca true, jeżeli dany element jest pierwszym w kolekcji,
- $middle – zwraca true, jeżeli dany element jest między pierwszy, a ostatnim w kolekcji,
- $last – zwraca true, jeżeli dany element jest ostatni w kolekcji,
- $even – zwraca true, jeżeli $index jest parzysty, w przeciwnym wypadku false,
- $odd – zwraca true, jeżeli $index jest nieparzysty, w przeciwnym wypadku false.
Ng-dblclick
Pozwala nam określić sposób zachowania elementu po dwukrotnym kliknięciu na jego powierzchnię.
<h1>{{ $ctrl.counter }}</h1> <button type="button" ng-click="$ctrl.click()">Zwiększ o 1</button> <button type="button" ng-dblclick="$ctrl.dblclick()">Zwiększ o 2</button>Ng-href
Tworzy dynamiczne linki zmieniające się pod wpływem interakcji użytkownika z interfejsem.
<a ng-href="http://www.adres.pl/{{$ctrl.counter}}">http://www.adres.pl/{{ $ctrl.counter }}</a>data-ng-keydown, data-ng-keypress, data-ng-keyup, ng-keyup
Odpowiadają za obsługę klawiatury:
- data-ng-keydown – wykonanie funkcji podczas wciśnięcia przycisku klawiatury,
- data-ng-keypress – wykonanie funkcji podczas wciskania przycisku klawiatury,
- data-ng-keyup – wykonanie funkcji podczas puszczania przycisku klawiatury,
- ng-keyup – pozwala nam na odczytanie kodu wciśniętego przycisku.
ng-mousedown, ng-mouseenter, ng-mouseleave, ng-mousemove, ng-mouseover, ng-mouseup
Odpowiadają za obsługę myszy:
- ng-mousedown – odpowiada za wykonanie funkcji po wciśnięciu przycisku myszy,
- ng-mouseenter – odpowiada za wykonanie funkcji po najechaniu myszą na element,
- ng-mouseleave – odpowiada za wykonanie funkcji tuż po opuszczeniu danego elementu,
- ng-mousemove – odpowiada za wykonanie funkcji podczas poruszania myszką po elemencie,
- ng-mouseover – odpowiada za wykonanie funkcji po najechaniu myszą na element,
- ng-mouseup – odpowiada za wykonanie funkcji po puszczeniu przycisku myszy.
Każde zdarzenie wysyła jako parametr obiekt zdarzenia, zapisywany dzięki $event.
<button ng-mousedown="$ctrl.clog('ngMousedown')" ng-mouseenter="$ctrl.clog('ngMouseenter')" ng-mouseleave="$ctrl.clog('ngMouseleave')", ng-mousemove="$ctrl.clog('ngMousemove')", ng-mouseover="$ctrl.clog('ngMouseover')" ng-mouseup="$ctrl.clog('ngMouseup')">Mysz</button>ng-readonly
Zadaniem tej dyrektywy jest zmiana pola input na tylko do odczyty w przypadku spełnienia określonych kryteriów. jeżeli wartość jest true, wtedy pole zostanie zablokowane.
<input type="text" ng-readonly="$ctrl.ngRead"> <input type="checkbox" ng-model="$ctrl.ngRead">ng-style
Dyrektywa ta pozwala programiście na dodawanie styli do wybranego elementu.
<p ng-style="$ctrl.ngStyle">Przykładowy tekst</p>ng-submit
Określa niestandardowe zachowanie aplikacji w przypadku przesłania formularza, dzięki przycisku z określonym typem submit.
<form data-ng-submit="$ctrl.submit()"> <input type="text" ng-model="$ctrl.submitText" name="text" /> <input type="submit" id="submit" value="Wyślij" /> </form>
Przykładowa aplikacja
Aplikacja jaką stworzyłem na potrzeby tego wpisu prezentuje wszystkie z omówionych dyrektyw.
Kod JS
var app = angular.module("app", ['ngSanitize']); app.component('appRoot', { templateUrl: 'app-root.html', controller: rootAppController }); function rootAppController() { var ctrl = this; ctrl.name = "Dyrektywy"; ctrl.bindHTML = "Przykładowy kod HTML"; ctrl.ngCloak = "Dyrektywa ngCloak"; ctrl.inputChange = ""; ctrl.change = function () { console.log(ctrl.inputChange); }; ctrl.ngClass = true; ctrl.users = [{ firstName: "Adam", lastName: "Kowalski" }, { firstName: "Kamil", lastName: "Wiśniewski" }, { firstName: "Ania", lastName: "Nowakowska" }, { firstName: "Marek", lastName: "Wójcik" }, { firstName: "Krystyna", lastName: "Nowak" }, ]; ctrl.counter = 0; ctrl.click = function () { ctrl.counter++; }; ctrl.dblclick = function () { ctrl.counter += 2; }; ctrl.clog = function (value) { console.log(value); }; ctrl.ngRead = true; ctrl.ngStyle = { color: 'yellow' }; ctrl.submitText = ""; ctrl.submit = function () { console.log(ctrl.submitText); }; }app-root.html
<div> <h1 ng-bind="$ctrl.name"></h1> </div> <div> <h2 ng-cloak>{{$ctrl.ngCloak}}</h2> </div> <div> <span ng-bind-html="$ctrl.bindHTML"></span> </div> <div> <input type="text" ng-model="$ctrl.inputChange" ng-change="$ctrl.change()"> </div> <div> <span ng-class="{ 'ng-class-true': $ctrl.ngClass, 'ng-class-false': !$ctrl.ngClass }">Dyrektywa ngClass</span> <input type="checkbox" ng-model="$ctrl.ngClass"> </div> <div> <table> <thead> <td>Lp.</td> <td>First Name</td> <td>Last Name</td> </thead> <tr ng-repeat="user in $ctrl.users" ng-class="{ 'table-even': $even, 'table-odd': $odd }"> <td>{{ $index + 1 }}</td> <td>{{ user.firstName }}</td> <td>{{ user.lastName }}</td> </tr> </table> </div> <div> <h1>{{ $ctrl.counter }}</h1> <button type="button" ng-click="$ctrl.click()">Zwiększ o 1</button> <button type="button" ng-dblclick="$ctrl.dblclick()">Zwiększ o 2</button> </div> <div> <a ng-href="http://www.adres.pl/{{$ctrl.counter}}">http://www.adres.pl/{{ $ctrl.counter }}</a> </div> <div> <input data-ng-keydown="$ctrl.clog('keydown')" placeholder="keydown"> <br> <input data-ng-keypress="$ctrl.clog('keypress')" placeholder="keypress"> <br> <input data-ng-keyup="$ctrl.clog('keyup')" placeholder="keyup"> <br> <p>Typing in the input box below updates the keycode</p> <input ng-keyup="event=$event"> <p>event keyCode: {{ event.keyCode }}</p> <p>event altKey: {{ event.altKey }}</p> </div> <div> <button ng-mousedown="$ctrl.clog('ngMousedown')" ng-mouseenter="$ctrl.clog('ngMouseenter')" ng-mouseleave="$ctrl.clog('ngMouseleave')" , ng-mousemove="$ctrl.clog('ngMousemove')" , ng-mouseover="$ctrl.clog('ngMouseover')" ng-mouseup="$ctrl.clog('ngMouseup')">Mysz</button> </div> <div> <input type="text" ng-readonly="$ctrl.ngRead"> <input type="checkbox" ng-model="$ctrl.ngRead"> </div> <div> <p ng-style="$ctrl.ngStyle">Przykładowy tekst</p> </div> <div> <form data-ng-submit="$ctrl.submit()"> <input type="text" ng-model="$ctrl.submitText" name="text" /> <input type="submit" id="submit" value="Wyślij" /> </form> </div>Pierwsza omawiana dyrektywa wyświetla napis Dyrektywy dzięki ng-bind.
Kolejny przykład prezentuje użycie ng-cloak. Przypominam, aby osiągnąć zamierzony efekt, o którym mówiłem na początku wpisu należy dodać klasy css [ng\:cloak], [ng-cloak], .ng-cloak.
ng-bind-html wstrzykuje nam do elementu span kod HTML <strong>Przykładowy kod HTML<strong>.
Następna omawiana dyrektywa w przykładowej aplikacji to ngChange, nasłuchuje zmian na polu input, po wpisaniu każdej litery następuje wyświetlenie obecnego ciągu znaków w konsoli.
ng-class zmienia kolor wyświetlanego tekstu w zależności od zaznaczonego checkboxa.
Kolejną omawianą dyrektywą jest ng-repeat, która wyświetla tabele użytkowników pokazując liczbę porządkową jako $index + 1, a także nadając klasę css w zależności od parzystości $index ($even i $odd).
ng-dblclick to kolejna dyrektywa, która przyjmuje funkcję zwiększającą wyświetlany licznik o 2.
ng-href określa link dzięki licznika wykorzystanego przy dyrektywie ng-dblclick.
Następne dyrektywy pokazuje sposób obsługi klawiszy. Efekty możemy zobaczyć w konsoli.
Kolejne dyrektywy pokazują sposób obsługi zdarzeń wywołanych przez mysz. Efekty możemy zobaczyć w konsoli.
ng-readonly za pomocą checkboxa ustawia pole input na tylko do odczytu.
ng-style określa kolor elementu p.
Ostatnia już dyrektywa odpowiada za wykonanie niestandardowej operacji po przesłaniu formularza dzięki przycisku z typem submit. W naszej aplikacji efektem będzie wyświetlenie w konsoli odczytanej wartości z pola tekstowego.
Efekty działania
Podsumowanie
Pisanie aplikacji w AngularJS dzięki wykorzystaniu tych dyrektyw staje się jeszcze bardziej przyjemne. Dają nam wiele możliwości rozbudowy naszych aplikacji takich jak: dynamiczne dodawanie klas lub styli css do elementów, obsługa zdarzeń muszy i klawiatury, a także wiele innych. Warto zaznaczyć, iż to nie wszystkie dostępne dyrektywy, a jedynie część. jeżeli chcesz poznać pozostałe zachęcam do zajrzenia w dokumentację omawianego frameworka.