DIY #13 - robimy prostą TODO listę w AngularJS! | DailyWeb.pl

DIY #13 - robimy prostą TODO listę w AngularJS!

Opublikowano 9 miesięcy temu - 13


Angular jest frameworkiem JavaScript, który pomaga w tworzeniu aplikacji single page, lub dynamicznych kawałków dla naszej strony. Jest frameworkiem umożliwiającym szybki development i ułatwiającym organizacje kodu. W tym tutorialu chciałbym przybliżyć wam pierwszą wersję Angulara. Z uwagi na to, że ma bardzo rozbudowaną społeczność i niski próg wejścia cały czas cieszy się dużą popularnością. Jeśli znasz podstawy JavaScriptu i HTML ten tutorial nie powinien sprawić ci problemu.

Zalety AngularJS

Największą z zalet Angulara jest według mnie two way binding, który polega na tym że zmiany w modelu są automatycznie odzwierciedlane w HTML oraz każda zmiana wartości w HTML jest automatycznie propagowana do modelu. Wydaje się prostym mechanizmem ale bardzo usprawnia pracę.

Kolejną z zalet jest niewątpliwie możliwość tworzenia dyrektyw. Dyrektywa nie jest niczym innym jak kawałkiem HTML wraz z pewną logiką która odpowiada za wszystko co ma się dziać wewnątrz. Jest to pewnego rodzaju komponent, który po stworzeniu możemy używać w wielu miejscach naszej aplikacji bez najmniejszego problemu. Cały jego kod będzie w jednym miejscu dzięki czemu jest łatwo nim zarządzać.

W AngularJS cały kod jest podzielony na moduły, dzięki temu cała aplikacja może składać się z mniejszych części. Pozwala to zachować niezależność między modułami. Może się to też przydać przy ładowaniu samego kodu, który da się podzielić na paczki z modułami i ładować w zależności od zapotrzebowania. Dość tego przydługiego wstępu, czas przejść do tutorialu podczas którego stworzymy... TODO listę!

TODO Lista

Założenia listy:

  • dodawanie nowych pozycji
  • kasowanie gotowych
  • podgląd ilości pozostałych i wszystkich zadań

Wstępna konfiguracja:

  1. tworzymy pusty plik HTML (dodajemy wymagane tagi html, head, body ;))
  2. załączamy skrypt Angulara:
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
    
  3. Kod naszej todo listy można pisać bezpośrednio w html lub dodać osobny plik. Na tym etapie nie ma to znaczenia.

Angular musi wiedzieć gdzie zaczyna się nasza aplikacji służy do tego dyrektywa ng-app. Wstawiamy ją jako atrybut do elementu który będzie naszą aplikacją. W naszym przypadku może to być tag <html> lub <body>

<html ng-app="todoApp">

W kodzie js musimy natomiast zarejestrować taki moduł – a więc:
angular.module('todoApp', []) - (dalsza część kodu wraz z objaśnieniami po sekcji HTML)

dodajemy teraz HTML do wyświetlania samej listy:

<div ng-controller="TodoListController">
    <h1>TODO</h1>
    <h3>Pozostało {{remaining()}} z {{list.length}}</h3>
    <a ng-click="archive()">Usuń ukończone</a>
    <ul>
      <li ng-repeat="item in list">
        <input type="checkbox" ng-model="item.done" />
        <span>{{item.title}}</span>
      </li>
    </ul>
    <input type="text" ng-model="newTodo" /><button ng-click="add()">Dodaj</button>
  </div>

sporo nowości prawda? Omówię wszystko zaczynając od góry:

ng-controller – informujemy Angulara że w tym elemencie i elementach znajdujących się w nim kontrole sprawuje TodoListController co oznacza że wszystkie funkcje i zmienne których używamy będą szukane bezpośrednio w kodzie tego kontrolera.

Klamry {{ }} - służą do wyświetlania treści. Angular wie że w nich znajduje się zmienna lub wywołanie funkcji i wyświetla odpowiednią wartość. W klamrach można również wykonywać operacje arytmetyczne, łączyć stringi i używać filtrów. Ale na potrzeby tego tutorialu będziemy używać tylko funkcji i zmiennych.

remaining() - wywołanie funkcji która zwraca ilość niewykonanych zadań

list.length – w tablicy list przetrzymujemy wszystkie zadania, tutaj wyświetlamy całkowitą ich ilość

ng-click="archive()" - ng-click to wbudowana w Angular dyrektywa która wywoła kod podany jako parametr w momencie kliknięcia na element. Angular udostępnia więcej takich dyrektyw. Pełną listę można znaleźć tutaj https://docs.angularjs.org/api/ng/directive

archive() - kolejna funkcja która usuwa wszystkie wykonane zadania z listy

ng-repeat="item in list" – dyrektywa pętli która wyświetla wszystkie elementy z tablicy list. Element LI będzie powielany dla każdego elementu tablicy. item jest referencją do obiektu listy.

ng-model="item.done" – przypisujemy wartość checkboxa do property done obiektu z tablicy list. done będzie przełączane pomiędzy true i false po kliku w checkbox, tutaj możemy zaobserwować two way binding który automatycznie zaznaczy chceckbox jeśli wartość w done będzie true.

item.title – nazwa zadania

ng-model="newTodo" – wartość wpisana w input będzie przypisana do zmiennej  newTodo. Wykorzystujemy ją do dodawania nowych wpisów do listy.

ng-click="add()" - kolejne użycie dyrektywy ng-click. Po kliku zostanie wywołana funkcja add w której dodamy nowy wpis do naszej listy

Teraz czas na kod JavaScript:

angular.module('todoApp', [])
 .controller('&lt;wbr&gt;TodoListController', function($scope) {
 $scope.list = [
 {title: 'zadanie 1', done: true},
 {title: 'zadanie ', done: false},
 ];

$scope.remaining = function() {
 var count = 0;
 angular.forEach($scope.list, function(todo) {
 count += todo.done ? 0 : 1;
 });
 return count;
 };

$scope.archive = function() {
 var oldTodos = $scope.list;
 $scope.list = [];
 angular.forEach(oldTodos, function(todo) {
 if (!todo.done) $scope.list.push(todo);
 });
 };

$scope.add = function(){
 $scope.list.push({title: $scope.newTodo, done: false});
 $scope.newTodo = '';
 };
 });&amp;nbsp;

zaczynając od góry:

angular.module('todoApp', []) - definiujemy moduł  todoApp w naszej aplikacji, pusta tablica przekazana jako drugi parametr może zawierać zależności innych modułów jakie będą nam potrzebne. W tym tutorialu nie mamy takich zależności dlatego jest pusta.

controller('TodoListController', function($scope) {}) - definiujemy kontroler do którego możemy odnosić się w widokach poprzez dyrektywę ng-controller="TodoListController". Pierwszym argumentem jest nazwa kontrolera (warto zwrócić uwagę na nazewnictwo – standardem jest używani "Controller" lub "Ctrl" jako ostatniego człona nazwy, pozwala to zachować porządek w kodzie). Drugim parametrem jest funkcja która będzie zawierać definicje naszego kontrolera. Jako parametry przekazujemy nazwy zależności któe będziemy używać w kontrolerze (korzystamy tutaj z Dependency Injection po więcej informacji odsyłam do dokumentacji https://docs.angularjs.org/guide/di ).

$scope – jest to obiekt który będzie bezpośrednio dostępny w widoku, jeśli przypiszemy do niego funkcje lub property będziemy mogli się do nich odnosić w widoku poprzez ich nazwę.

$scope.list – tworzymy tablicę z listą wpisów, będzie dostępna w widoku pod nazwą list. Każdy element składa się z tytułu title oraz statusu wykonania done.

$scope.remaining – pierwsza funkcja którą definiujemy będzie zwracać pozostałą ilość niewykonanych zadań. Używamy tutaj pętli foreach  angular.forEach która iteruje po tablicy list i sprawdza czy dany element ma status done ustawiony na false. Jeśli tak zwiększamy zmienną count a na końcu ją zwracamy żeby mogła być wyświetlona w widoku.

$scope.archive – funkcja która usuwa wszystkie skończone wpisy z listy. Znów używamy forEach do iteracji po liście. Wpisy które są nieukończone zostają dodane do tablicy przez funkcje push(). Zwróć uwagę że w tej funkcji nie zwracamy żadnej wartości.

$scope.add – funkcja która dodane nowy element do listy. Znów posługujemy się funkcją push(). Title nowego zadania jest brany ze zmiennej newTodo którą po dodaniu ustawiamy na pusty string.

I to by było na tyle, cały kod naszej todo listy jest dostępny pod linkiem https://jsfiddle.net/7bpzc86m/ Jest to modyfikacja przykładu ze strony dokumentacji Angualra. Nasza aplikacja jest bardzo prosta ale pozwala zrozumieć podstawy Angulara i pokazuje jego możliwości. Jeśli masz jakieś uwagi do tutorialu lub czegoś nie rozumiesz postaram się to wyjaśnić w komentarzach, w kolejnej części zagłębimy się w dyrektywy które pozwalają na zamykanie kodu w mniejsze bloki i znacznie ułatwiają pracę nad powtarzalnymi elementami naszej aplikacji.

Efekt?