Tym razem krótki wpis. Aby utrwalić wiedzę, która przekazałem wczoraj, napisałem prościutki program wykorzystując framework AngularJS. W zaledwie parunastu linijkach JavaScriptu udało się bez problemu napisać pełną, działającą aplikację.
Przedstawiam wam Zgadywankę. Jest to bardzo prosta aplikacja w AngularJS. Powstała ona na podstawie informacji, które zawarłem w ostatnim poście.
Dzisiejsza aplikacja to (a jakże) gra 🙂 . Gracz musi odgadnąć hasło na podstawie podpowiedzi wyświetlonej na ekranie. Hasło wybierane jest losowo przy każdym zainicjalizowaniu gry. Lista możliwych haseł i odpowiedzi znajduje się w skrypcie. Jeżeli gracz odgadnie hasło, gra wyświetli gratulacje oraz przycisk pozwalający na rozpoczęcie od nowa. Nieudane próby będą zliczane a ich suma wyświetlana na ekranie.
Tak jak ostatnio, aby ten przykład zadziałał, musi zostać uruchomiony na lokalnym serwerze. Przejdźmy do kodu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
<!DOCTYPE html> <html data-ng-app='zgadywanka'> <head> <title>Angular Zgadywanka - js.N00b jsdn.pl</title> <meta charset='utf-8'> <script type="text/javascript" src='https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js'></script> <script type="text/javascript"> var zgadywanka = angular.module('zgadywanka', []); var model = [{ opis: 'Korzeni nie widziało niczyje oko, A przecież to coś sięga bardzo wysoko, Od drzew wybujało wspanialej, Chociaż nie rośnie wcale.', word: 'GÓRA' }, { opis: 'Nie ma skrzydeł, a trzepocze, Nie ma ust, a mamrocze, Nie ma nóg, a pląsa, Nie ma zębów, a kąsa.', word: 'WIATR' }, { opis: 'Nie można tego zobaczyć ani dotknąć palcami, Nie można wyczuć węchem ani usłyszeć uszami; Jest pod górami, jest nad gwiazdami, Pustej jaskini nie omija, Po nas zostanie, było przed nami, Życie gasi, a śmiech zabija.', word: 'MROK' }, { opis: 'Nie oddycha, a żyje, Nie pragnie, a wciąż pije', word: 'RYBA' }, { opis: 'Pudełko bez zawiasów, klucza ani wieka, A przecież skarb złocisty w środku skryty czeka.', word: 'JAJKO' }]; zgadywanka.controller('guessController', function($scope){ $scope.words = model; $scope.initGame = function(){ $scope.guess = ''; $scope.guessNum = 0; $scope.wordGuessed = false; $scope.chosenWord = $scope.words[Math.floor(Math.random()*$scope.words.length)] } $scope.checkWord = function(){ if(($scope.guess).toUpperCase() === $scope.chosenWord.word) { $scope.wordGuessed = true; } $scope.guessNum++; $scope.guess = ''; } $scope.initGame(); }) </script> </head> <body data-ng-controller='guessController'> <h1>Zgadywanka</h1> <p>Podpowiedź: <i>{{chosenWord.opis}}</i></p> <input type='text' data-ng-model='guess'> <input type='button' data-ng-hide='wordGuessed' data-ng-click='checkWord()' value='sprawdz hasło'><br> <p>Ilość prób: {{guessNum}}</p> <input type='button' data-ng-click='initGame()' value='rozpocznij grę od nowa'><br> <h2 data-ng-show='wordGuessed'>Gratulacje! Zgadłes! Odpowiedź to {{chosenWord.word}}</h2> </body> </html> |
Jak widać, cała aplikacją mieści się w 60 linijkach. Warto zwrócić uwagę, że nawet wizualnie w kodzie jest wyraźny podział na model, kontroler i widok (html) 🙂 . Omówię po kolei każdy z tych elementów.
Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
var zgadywanka = angular.module('zgadywanka', []); var model = [{ opis: 'Korzeni nie widziało niczyje oko, A przecież to coś sięga bardzo wysoko, Od drzew wybujało wspanialej, Chociaż nie rośnie wcale.', word: 'GÓRA' }, { opis: 'Nie ma skrzydeł, a trzepocze, Nie ma ust, a mamrocze, Nie ma nóg, a pląsa, Nie ma zębów, a kąsa.', word: 'WIATR' }, { opis: 'Nie można tego zobaczyć ani dotknąć palcami, Nie można wyczuć węchem ani usłyszeć uszami; Jest pod górami, jest nad gwiazdami, Pustej jaskini nie omija, Po nas zostanie, było przed nami, Życie gasi, a śmiech zabija.', word: 'MROK' }, { opis: 'Nie oddycha, a żyje, Nie pragnie, a wciąż pije', word: 'RYBA' }, { opis: 'Pudełko bez zawiasów, klucza ani wieka, A przecież skarb złocisty w środku skryty czeka.', word: 'JAJKO' }]; |
Zaraz po zadeklarowaniu modułu, tworzę zmienną model. Tutaj przechowuję dane aplikacji w formie tablicy. Elementy tablicy to obiekty o dwóch polach opis oraz word. Pierwsze pole to podpowiedź którą otrzyma gracz. Drugie, to hasło, które musi odgadnąć. Hasła zapisane są z wielkich liter, aby później łatwiej było porównać je z odpowiedzią udzieloną przez gracza.
Kontroler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
zgadywanka.controller('guessController', function($scope){ $scope.words = model; $scope.initGame = function(){ $scope.guess = ''; $scope.guessNum = 0; $scope.wordGuessed = false; $scope.chosenWord = $scope.words[Math.floor(Math.random()*$scope.words.length)] } $scope.checkWord = function(){ if(($scope.guess).toUpperCase() === $scope.chosenWord.word) { $scope.wordGuessed = true; } $scope.guessNum++; $scope.guess = ''; } $scope.initGame(); }) |
Wewnątrz kontrolera, przypisuje model do pola scope’a words. Następnie tworze dwie metody initGame oraz checkWord. Służą one kolejno do rozpoczęcia nowej gry, oraz do sprawdzenia czy gracz podał dobrą odpowiedź.
initGame ustawia pola scope’a na wartości początkowe. guess, który będzie zawierał odpowiedź gracza jest otrzymuje wartość pustego łańcucha znaków. guessNum przechowywać będzie liczbę prób, którą gracz podjął w danej rozgrywce. Na początku wynosi zero. Pole wordGuessed zawiera wartość boolowską. Dopóki hasło jest nieodgadnięte, będzie się równało false. Ostatnia rzecz, która dzieje się w metodzie initGame to wybranie losowo jednego obiektu zagadki spośród puli w words i przypisanie go do pola chosenWord.
Metoda checkWord służy do sprawdzenia, czy zmienna guess jest równa polu word w obieckie chosenWord. Jeżeli tak, wartość wordGuessed ustawiana jest na true. W innym wypadku, metoda inkrementuje zawartość zmiennej guessNum i ustawia guess na pusty łańcuch znaków.
Na końcu kontrolera wywołuję jeszcze metodę initGame. Dzięki temu po otwarciu aplikacji, potrzebne zmienne zostaną zainicjalizowane. Zgadywanka już gotowa w dwóch trzecich. Teraz kolej na ostatni element czyli widok.
Widok
1 2 3 4 5 6 7 8 9 |
<body data-ng-controller='guessController'> <h1>Zgadywanka</h1> <p>Podpowiedź: <i>{{chosenWord.opis}}</i></p> <input type='text' data-ng-model='guess'> <input type='button' data-ng-hide='wordGuessed' data-ng-click='checkWord()' value='sprawdz hasło'><br> <p>Ilość prób: {{guessNum}}</p> <input type='button' data-ng-click='initGame()' value='rozpocznij grę od nowa'><br> <h2 data-ng-show='wordGuessed'>Gratulacje! Zgadłes! Odpowiedź to {{chosenWord.word}}</h2> </body> |
Tutaj sprawa jest już prosta. Kontroler guessController przypisuję do elementu body. Pod tytułem wyświetlam podpowiedź dla gracza znajdującą się w obiekcie scope’a chosenWord w polu opis. Aby dołączyć tekstu do widoku, używam notacji z podwójnymi nawiasami klamrowymi.
Następnie dodaje okno tekstowe, którego wartość łącze z polem scope’a guess. Robię to za pomocą dyrektywy (atrybutu) ng-model. Dzięki temu, wartość wyświetlana w okienku oraz wartość pola, będą zawsze takie same. Jeżeli jedno się zmieni, zostanie to odzwierciedlone w drugim.
Kolejny element to przycisk. Dyrektywa ng-click powoduje, że po jego kliknięciu wywołana zostanie metoda checkWord. Nastąpi porównanie zawartości okna tekstowego (które jest połączone z polem guess) z wylosowanym słowem. Oprócz tego, przycisk zawiera dyrektywę ng-hide. Działa ona, w następujący sposób, element zostanie ukryty, jeżeli to co zostało podane jako wartość ewauluje się na true. W tym przypadku, jeżeli pole wordGuessed, wyniesie true, czyli jak gracz odgadnie słowo.
Pod przyciskiem dołączam tekst wyświetlający ilość prób, które podjął gracz. Tak jak zawsze używam notacji podwójnych nawiasów klamrowych.
Następny element to drugi przycisk, służy on do rozpoczęcia nowej gry. Dzięki dyrektywie ng-click, która po kliknięciu wywołuje metodę initGame. Do tego elementu przypisałem jeszcze jedną dyrektywę ng-show. Działa odwrotnie do ng-hide. Jeżeli jej wartość ewauluje się na true, element zostanie pokazany. Wartość to znów wordGuessed. Czyli ten przycisk pokaże się po odgadnięciu hasła.
ng-show używam też do ostatniego elementu, czyli tekstu gratulacyjnego. Będzie widoczny po odgadnięciu hasła.
I to cała aplikacja. Tak jak pisałem, nie jest zbyt skomplikowana. Myślę, że ilustruje też, jak łatwo jest obsługiwać się angularem. Nie trudno wyobrazić sobie wykorzystywanie tych intuicyjnych i przyjemnych w obsłudze opcji do zbudowania bardziej skomplikowanej aplikacji, o znacznie złożonym modelu.
To na pewno nie koniec Angulara na moim blogu, spodziewajcie się więcej wpisów na ten temat 🙂 Jeżeli chcesz być na bieżąco z tym co tu zamieszczam, zachęcam do polubienia mojej strony na facebooku. Jest ona bardzo często uaktualniana o najświeższe informacje.