Aplikacje SPA, Angular, TypeScript dr hab. inż. Marek Wojciechowski
Ewolucja aplikacji webowych (pre-spa) Model 1 (pierwotny model WWW) Strony powiązane linkami (jak dokumenty WWW) Model 2 (MVC) Kontroler decyduje o nawigacji Strony nie odwołują się do siebie bezpośrednio Model 3 (MVC + komponenty) Wersja Model 2 inspirowana sposobem działaniem aplikacji desktopowych: komponenty obsługujące zdarzenia Przebudowa i przeładowanie strony w reakcji na zdarzenie (Model 2 / Model 3) + Ajax Częściowa eliminacja nawigacji i odświeżania stron Źródło: http://itsnat.sourceforge.net/php/spim/spi_manifesto_en.php 2
Single Page Applications (SPA) Strona startowa aplikacji jest jedyną stroną pobieraną w całości z serwera (potem interakcje Ajax, WebSocket) Strona aplikacji nie przeładowuje się w czasie pracy z nią Nie następuje nawigacja do innych stron Zmienia się stan (i wygląd) strony w przeglądarce User Experience (UX) podobny do aplikacji desktopowych Technologie: HTML5, CSS, JavaScript, Ajax, WebSocket Frameworki: Angular, Ember.js, Meteor.js, ExtJS, React, 3
Single Page Interface (SPI) Czy model SPA jest odpowiedni tylko dla aplikacji webowych (web applications) czy również dla witryn (web sites)? Pytanie otwarte, różne stanowiska Głos na tak : The Single Page Interface Manifesto (http://itsnat.sourceforge.net/php/spim/spi_manifesto_en.php) Problemy przy tworzeniu witryn mocno opartych o Ajax: Zakładki do stanu strony po jej zmianie Ajaksem, historia przeglądarki Indeksowanie przez wyszukiwarki (Search Engine Optimization (SEO)) Model biznesowy oparty o liczbę odwiedzin stron Potrzeba wyskakujących okienek (pop-up) Wolne pierwsze wyświetlenie strony 4
Stan aplikacji SPA/SPI W tradycyjnej aplikacji webowej sekwencja stanów aplikacji to sekwencja stron W aplikacji SPA/SPI każda częściowa zmiana strony w przeglądarce (Ajax, DOM) skutkuje zmianą stanu Stany aplikacji SPA/SPI można podzielić na: Stany fundamentalne (odpowiadałyby stronom w modelu tradycyjnym, warte tworzenia zakładek) Stany drugorzędne Przykład kategoryzacji stanów: obsługa logowania Ekran do wprowadzenia użytkownika i hasła (fundamentalny) Informacje o błędach w formularzu logowania (drugorzędny) Ekran powitalny po zalogowaniu (fundamentalny) 5
Zakładki i historia przeglądarki w SPA Opis problemu Dla aplikacji SPA samoistnie pojawi się tylko jeden wpis w historii przeglądarki Ewentualna zakładka będzie prowadzić do strony w wersji pobranej z serwera (stan początkowy) Programowa podmiana (JS) window.location (location.href) może spowodować odwołanie przeglądarki do serwera Rozwiązania Wykorzystanie adresów URL adresujących fragmenty stron (#) Podmiana adresu URL (przez location.href lub location.hash) na różniący się od poprzedniego treścią po znaku # nie powoduje odwołania do serwera Wykorzystanie HTML 5 History API: history.pushstate [W obu przypadkach obsługa nawigacji Back/Forward jest programowa] 6
Rozwiązania pozostałych problemów modelu SPA/SPI Search Engine Optimization (SEO) Specjalny tryb nawigacji dla robotów (web crawlers) <a href="url page" onclick="return false"> </a> (roboty obecnie ignorują JavaScript) Linki w formacie (Ajax-crawlable): #! (wyszukiwarka widząc taki URL zmienia go na zawierający?_escaped_fragment_ a aplikacja odpowiada snaphotem strony HTML) Zwiększanie licznika odwiedzin stron Ramka IFRAME prowadząca do pustej strony ze skryptem Okienka pop-up Problemy: brak okien modalnych w przeglądarce, współdzielenie stanu między oknami Rozwiązanie: Symulowanie okienek modalnych/niemodalnych za pomocą elementów HTML z odpowiednim pozycjonowaniem 7
Architektura aplikacji SPA Źródło: http://singlepageappbook.com/single-page.html Cechy architektury: Write-only DOM Cały stan aplikacji w komponentach modelu Widoki obserwujące zmiany w modelu Modularyzacja z jak najmniejszymi zależnościami między modułami Jak największa izolacja od implementacji DOM w przeglądarce Brak kontrolera (znanego z MVC) 8
Kontrolery w aplikacjach SPA? Część pierwszych frameworków dla aplikacji SPA (np. AngularJS 1.x) przeniosło do przeglądarki wzorzec architektoniczny MVC sprawdzony i powszechny po stronie serwerowej Separacja modeli i widoków powszechnie akceptowana, ale czy spoiwem powinien być kontroler? Koncepcja Model-View-Whatever, MV* Typowe zadania przydzielane kontrolerom w SPA: Obsługa zdarzeń w modelu DOM Renderowanie szablonów widoków Synchronizacja widoków z modelami Lepiej jest powyższe zadania rozdzielić (zasada pojedynczej odpowiedzialności) 9
Angular (2.x) / AngularJS (1.x) Front-endowy framework do tworzenia aplikacji webowych Rozwijany pod skrzydłami Google Głównie zorientowany na aplikacje SPA Od wersji 2.0 pozycjonowany jako jeden framework dla aplikacji webowych, mobilnych i desktopowych Zaimplementowany w języku JavaScript i (od wersji 2.0) TypeScript, wykorzystujący HTML i CSS Główna motywacja: HTML jest odpowiedni dla stron WWW, ale nieodpowiedni dla aplikacji webowych 10
AngularJS 1.x Framework oparty o wzorzec MVC po stronie klienta Obiekt scope ($scope) jako sposób współdzielenia danych między kontrolerem a widokiem Spoiwo między kontrolerem i widokiem, pełni rolę ViewModel Wiązanie danych (data binding): Interpolacje {{ }}, one-way data binding, two-way data binding Dyrektywy ng-* dodatkowe atrybuty dla elementów HTML np. ng-app, ng-model, ng-repeat Filtry filtracja, sortowanie, transformacja danych 4 rodzaje komponentów do logiki biznesowej: Factory, Service, Provider, Value Routing nawigacja między widokami aplikacji SPA Modularność (Angular modules) 11
AngularJS 1.x Hello World <!doctype html> <html ng-app> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"> </script> </head> <body> <div> <label>name:</label> <input type="text" ng-model="yourname" placeholder="enter a name here"> <hr> <h1>hello {{yourname uppercase}}!</h1> </div> </body> </html> Na podstawie: https://angularjs.org/ 12
Web Components Zbiór cech dodawanych do specyfikacji HTML i DOM Częściowo wspierany przez współczesne przeglądarki Wsparcie dla starszych przeglądarek poprzez polyfille Intencja: przeniesienie komponentowego modelu tworzenia aplikacji na grunt WWW umożliwienie tworzenia reużywalnych komponentów (widgets) do wykorzystania na stronach WWW i po stronie front-endu aplikacji webowych Cechy (rodzaje Web Components) Custom Elements - APIs to definiowania nowych elementów HTML Shadow DOM enkapsulacja DOM i styli w elemencie HTML Przeglądarka renderuje DOM elementów z Shadow DOM bez umieszczania ich w DOM głównego dokumntu HTML Imports deklaratywny import dokumentów HTML do innych dokumentów HTML HTML Templates szablony fragmentów HTML 13
Angular 2 na tle Angular 1.x Istotne zmiany w porównaniu z Angular 1.x Właściwie nowy framework Brak zgodności wstecz, opcja migracji i współistnienia obu wersji w obrębie jednej aplikacji Duże zmiany w czasie jego rozwoju (Alpha->Developer Preview->Beta->Final) wiele tutoriali nieaktualnych Witany przez deweloperów z mieszanymi uczuciami Przyczyny radykalnych zmian: Rozwój języka JavaScript, pojawienie się języka TypeScript Rozwój przeglądarek Nowe trendy, np. Web Components Nadmierna komplikacja niektórych aspektów Angular 1.x (np. kilka rodzajów komponentów logiki biznesowej) Problemy wydajnościowe (np. gdy dużo danych w $scope) 14
Cechy Angular 2 (zalety na tle 1.x) Framework również dla urządzeń mobilnych Większa modularność Wsparcie tylko współczesnych przeglądarek Uproszczenie frameworka przez brak workarounds dla starszych Orientacja na język TypeScript Choć możliwe jest programowanie w czystym JavaScript Wykorzystanie elementów ECMAScript 2015 Dynamiczne ładowanie Prostszy routing, serwisy do logiki biznesowej Poprawione wstrzykiwanie zależności Komponenty i dyrektywy zamiast kontrolerów i $scope Programowanie reaktywne (RxJs) 15
TypeScript Nadzbiór języka JavaScript rozwijany przez Microsoft Ze względu na postulowaną nieodpowiedniość JS dla dużych aplikacji Powstał jako rozszerzenie ECMAScript 5, z uwzględnieniem cech przewidywanych w ECMAScript 6 Transpilowany do kodu JavaScript Najważniejsze cechy języka TypeScript: Klasy, moduły, funkcje strzałkowe, param. opcjonalne/domyślne (ES6) Składowe public (domyślnie), protected i private, przestrzenie nazw Adnotacje typu i kontrola typów na etapie kompilacji Automatyczna dedukcja typu (type inference) Interfejsy, klasy używane jako interfejsy (implements) Typy generyczne (<>), typy wyliczeniowe (enum), unie (union type), krotki (tuple) Domieszki (mixins) w części implementowane programowo Dekoratory (@) 16
AngularJS 2.x Hello World import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<h1>hello {{name}}</h1>` }) export class AppComponent { name: string = 'Marek'; } component = directive + template Na podstawie: https://angular.io/ 17