Zawartość
- Konfigurowanie HTML
- Modele, sklepy i pełnomocnicy
- Wiążąc to wszystko razem
- Na starcie:
- Gdy użytkownik dotknie pozycji menu:
- Gdy użytkownik kliknie miniaturę:
- Nowe filmy
- Gotowe!
Ten artykuł ukazał się pierwotnie w numerze 213 magazynu .net - najlepiej sprzedającego się magazynu na świecie dla projektantów i programistów stron internetowych.
Sencha Touch to wieloplatformowa biblioteka przeznaczona dla urządzeń dotykowych nowej generacji. Oznacza to, że możemy wykorzystać te wszystkie lata doświadczenia front-end do tworzenia natywnych aplikacji internetowych na urządzenia z systemem iOS i Android. Poza tym będą działać wspaniale na komputerach stacjonarnych opartych na WebKit
przeglądarki, Chrome i Safari.
Najnowszą wersję można pobrać ze strony sencha.com/products/touch/download. Dokumentacja, przykłady i społeczność są znakomite, więc dodaj je do zakładek. Dokumentacja API znajduje się pod adresem docs.sencha.com/touch/1-1/.
Więc co sprawia, że jest tak wyjątkowy? Cóż, ludzie stojący za Sencha (opartym na ExtJS) wykonali dla nas całą ciężką pracę i stworzyli bogaty i niezwykle potężny zestaw narzędzi do projektowania i kontrolowania Twojej aplikacji. Dodatki zawarte:
1. Solidne komponenty układu, w tym nagłówki, paski menu, popover, panele i karuzele
2. Zdarzenia niestandardowe, stworzone dla telefonów komórkowych, w tym stuknięcie, dwukrotne stuknięcie, machnięcie i szczypanie
3. Przejścia przyspieszane sprzętowo
4. Niesamowity system szablonów oparty na danych
Oznacza to, że możesz łatwo tworzyć układy podobne do aplikacji, które mają wszystkie przejścia i interakcje, jakich oczekują użytkownicy na swoich urządzeniach mobilnych, z ekranami, które można łatwo aktualizować ze źródła danych. W trakcie tego samouczka przekonasz się, że praktycznie bez kodu HTML, odrobiny kodu CSS i kilkuset wierszy kodu JavaScript (w tym komentarzy) możemy stworzyć coś imponującego dla Twojego iPada. Czy jest fajnie, nie?
Zamierzamy stworzyć aplikację na iPada, która pobierze najnowsze (lub przypadkowe) filmy z uroczego kanału Vimeo „Staff Picks” i umożliwi użytkownikom przeglądanie tych stron filmów w karuzeli i stukanie, aby oglądać ulubione filmy w wyskakującym okienku . W tle będziemy korzystać z magazynów danych i serwerów proxy Sencha, więc aktualizacja jest banalnie prosta. Na koniec będziemy przechowywać dane lokalnie, abyśmy mogli zapisać stan. Zacznijmy...
Konfigurowanie HTML
To nie może być prostsze. Zaczynamy od pustego ciało> tag, dodaj pliki JavaScript i CSS dla Sencha Touch i OAuth do pliku głowa>, a na końcu nasze własne pliki aplikacji JavaScript i CSS. Spójrzmy:
! DOCTYPE html> html> head> title> Just One More / title> link rel = "stylesheet" href = "resources / css / sencha-touch.css" /> link rel = "stylesheet" href = "resources / css / jom.css "/> skrypt src =" src / js / sencha-touch.js "> / script> script src =" src / js / oauth / sha1.js "> / script> script src =" src / js / oauth / oauth.js "> / script> script src =" src / js / jom.js "> / script> / head> body> / body> / html>
Teraz możemy rozpocząć pracę z naszym głównym plikiem aplikacji. Sencha Touch strzela onReady zdarzenie po zakończeniu konfigurowania strony pod kątem zdarzeń dotykowych i tym podobnych. Po prostu dodajemy w tym nasz kod onReady zdarzenie.
Ext.setup ({tabletStartupScreen: ’Default-Landscape.png’, icon: ’appIcon256.png’, glossOnIcon: false, onReady: function () {// Nasz kod znajdzie się tutaj ...};});
Tak więc, po ustawieniu kilku oczywistych zmiennych dla naszej aplikacji, możemy rozpocząć tworzenie naszego kodu.
Najpierw zdefiniujemy model i zapiszemy dla naszych danych, następnie utworzymy widoki, a na koniec stworzymy Ajax, aby to wszystko zasilić.
Modele, sklepy i pełnomocnicy
Zdefiniujmy kilka terminów. Modele opisują informacje, które przechowujemy dla obiektu (w naszym przypadku filmy). Pobieramy nasze dane za pośrednictwem serwera proxy, który przekształca poszczególne elementy danych w instancje modelu. Te instancje są następnie przechowywane w sklepie, który zapełnia nasze poglądy.
Najpierw opiszemy nasz model, podając pola i metody, które powinien mieć film:
// Skonfiguruj model, który będzie przechowywany w naszym StoreExt.regModel ('Video', {fields: ['id', 'available', 'description', 'height', 'thumbnail_medium', 'thumbnail_large', 'title ',' url ',' username ',' width ',' watched '], markAsWatched: function () {var videoId = this.data.id; if (! isVideoWatched (videoId)) {localStorage.watched + = videoId + ',';} this.set ('obserwowane', 'obserwowane'); this.store.sync ();}});
Pola są proste; otrzymamy je bezpośrednio z Vimeo API. Dodajemy dwa dodatkowe pola: dostępny, dzięki któremu możemy powiedzieć użytkownikom, które filmy mają wersje mobilne (a więc są dostępne na iPadzie) oraz Obejrzane, aby śledzić, które obejrzeli. Sklep i serwer proxy są nieco bardziej złożone.
// Nasz sklep JSON, który używa proxy powiązanego z localstoragevar videoStore = new Ext.data.JsonStore ({storeId: 'videos', proxy: {id: 'video', model: 'Video', type: 'localstorage', reader : {type: 'json', root: 'video'}}, listeners: {add: {fn: function (store, records, index) {handleVideosAddedToStore (store, records, index);}}, load: {fn: function (store, records, index) {handleVideosLoadedFromLocalStorage (store, records, index);}}, clear: {fn: function (store, records) {handleVideosRemovedFromStore (store, records);}}}});
Nadajemy sklepowi identyfikator i definiujemy jego proxy, które działa jako pomost między naszym źródłem danych a naszym sklepem:
1. typ: localStorage: oznacza to, że dane będą synchronizowane z lokalną pamięcią urządzenia HTML5
2. model: filmy: jest to model, który zdefiniowaliśmy wcześniej i na jego podstawie proxy będzie tworzyć instancje
3. czytelnik - określa, jakiego rodzaju danych oczekuje serwer proxy oraz katalog główny w obiekcie JSON.
Następnie dołączamy detektory, kiedy dane są dodawane do sklepu (z naszego wywołania Ajax), kiedy dane są ładowane do sklepu (z Lokalny magazyn za pośrednictwem naszego proxy) i do czasu, gdy wyczyścimy sklep. Każda z tych funkcji nasłuchujących po prostu wywołuje updateCarousel, do którego wkrótce dojdziemy.
Modele, sklepy, serwery proxy i czytelnicy są najtrudniejszymi do zaakceptowania, dlatego warto zapoznać się z różnymi opcjami w dokumentacji interfejsu API. Ale to modelowa strona definiowanych rzeczy. Przejdźmy do komponentów układu. Gdybyśmy mieli przedstawić naszą aplikację w prostym pseudokodzie, wyglądałoby to tak:
wrapper> header> logo> menu> / header> carousel> page1> page2> page3> page4> / carousel> / wrapper>
Lubię pracować od wewnątrz, więc utworzymy cztery strony (Numer stron poniżej) dla naszej karuzeli i przechowuj je w tablicy, do której będziemy mieć dostęp później:
// Utwórz strony dla carouselvar pages = []; for (var i = 0; inumberOfPages; i ++) {pages.push (new Ext.Component ({id: 'page' + i, cls: 'page', tpl: ['tpl for = ".">', 'div id = "summary {data.id}">', 'img src = "{data.thumbnail_medium}" />','h3>{data.title}/ h3> ',' / div> ',' / tpl> ']}));}
Każda strona otrzymuje pomysłowo nazwany identyfikator Strona 1, Strona 2 i tak dalej, i równie pomysłową klasę strona.
Najfajniejsza część to tpl sekcja, w której tworzymy szablon HTML dla każdej miniatury wideo. Kiedy więc zaktualizujemy nasze strony tablicą filmów, każdy element div będzie miał identyfikator wideo, a img src otrzyma wartość parametru wideo miniatura_środka, h3 będzie tytułem i tak dalej.
Następnie tworzymy karuzelę:
// Utwórz carouselvar carousel = new Ext.Carousel ({id: 'carousel', items: pages, flex: 1, listeners: {tap: {element: 'el', fn: function (evt, target) {showEmbeddedVideo ( evt, target);}, delegat: '.summary'}}});
Plik przedmiotów karuzeli będą stronami, które zdefiniowaliśmy wcześniej, a zgiąć określa, jaką część ekranu powinna zajmować karuzela 1 będąc całą dostępną przestrzenią.
Dodajemy słuchacza dla zdarzenia „tap”, wykorzystując raczej sprytne podejście delegat parametr. Oznacza to, że zdarzenie tap jest uruchamiane tylko wtedy, gdy trafię element DOM z klasą streszczenie - który następnie zostanie przekazany jako argument „docelowy” do naszego showEmbeddedVideo treser.
// Utwórz nagłówek headervar = nowy Ext.Panel ({dock: 'top', id: 'header', height: 185, html: 'h1> Jeszcze tylko jeden / h1> ul id = "menu"> li id = "najnowsze"> Najnowsze / li> li id = "random"> Losowe / li> / ul> '});
Jedyną specjalną cechą nagłówka jest dok atrybut. Oznacza to, że nagłówek będzie „zadokowany” u góry i nie będzie przewijany razem z pozostałymi elementami ekranu.
// Utwórz opakowanie (które ma nagłówek i przewijanie o stałej wysokości) var wrapper = new Ext.Panel ({fullscreen: true, layout: {type: 'vbox', align: 'stretch'}, items: [carousel], dockedItems: [nagłówek]});
Na koniec tworzymy panel opakowujący, który pomieści wszystko. Na uwagę zasługuje układ atrybut, który dyktuje, że elementy w nim zawarte są ułożone jeden na drugim (vbox) i że jest rozciągnięty, aby wypełnić cały ekran.
Elementy i dockedItems to komponenty, które utworzyliśmy powyżej. Mamy więc zdefiniowany model i skonfigurowane elementy układu: teraz musimy tylko dodać trochę funkcji.
Wiążąc to wszystko razem
Funkcjonalna część aplikacji, ponownie wykorzystująca pseudokod, wygląda następująco:
Na starcie:
1. Załaduj filmy z lokalnej pamięci do sklepu
2. Zaktualizuj karuzelę
Gdy użytkownik dotknie pozycji menu:
3. Wykonaj połączenie Ajax, aby uzyskać więcej filmów
4. Dodaj je do sklepu i zsynchronizuj z powrotem do pamięci lokalnej
5. Zaktualizuj karuzelę
Gdy użytkownik kliknie miniaturę:
6. Wyświetl wideo w wyskakującym okienku
7. Oznacz wideo jako obejrzane w sklepie i lokalnej pamięci
Po uruchomieniu aplikacji wywołujemy plik w tym funkcjonować:
/ * INIT * / var init = function () {// Get state („latest” or „random”) state = getState (); if (! } // Ustaw menu na bieżący stan i dodaj obsługę tap handlersetSelectedMenuItem (stan); Ext.select ('li', false, 'menu'). On ({tap: handleMenuTap}); // Załaduj sklep z lokalnego magazynuvideoStore .load (); // Upewnij się, że mamy najnowsze filmy .if (state == 'latest') {getNewVideos ();}} ();
Po sprawdzeniu, czy użytkownik ostatnio oglądał najnowsze lub przypadkowe filmy (i odpowiednią aktualizacją menu), wczytujemy filmy z Lokalny magazyn do sklepu. To jest tak proste, jak dzwonienie videoStore.load ().
Sklep następnie odpala Załaduj zdarzenie, które obsłużyliśmy z włączonym odbiornikiem zdarzeń Sklep wideo wcześniej. Ten detektor zdarzeń zasadniczo nazywa się updateCarousel:
var updateCarousel = function (data) {// Przenieś karuzelę z powrotem do startcarousel.setActiveItem (0, 'slide'); // Ukryj ładowanie messageloading.hide (); // Podziel dane na strony dla (var i = 0; inumberOfPages; i ++ ) {// Podziel nasze dane na 4 pagesvar page = pages [i]; var pageStart = i * numberOfVideosPerPage; var pageEnd = pageStart + numberOfVideosPerPage; // Pobierz pierwsze x wideo (stronę) z datavar pageData = data. slice (pageStart, pageEnd); // Dodaj tę stronę do stron w carouselpage.update (pageData);}};
updateCarousel zawiera szereg filmów. Dla każdej strony w naszej karuzeli zamierzamy pobrać fragment tych filmów o rozmiarze strony (pageData będzie tablicą 12 filmów) i załaduj je na stronę, dzwoniąc page.update (pageData).
Nowe filmy
Kiedy definiowaliśmy strony karuzeli, zdefiniowaliśmy szablon (plik tpl atrybut), który jest używany, gdy wywołujemy page.update - dla każdego filmu w formacie pageData tablica, div jest tworzony z identyfikatorem wideo, h3 z tytułem i tak dalej.
W konsekwencji, gdy użytkownik stuka najnowszy lub losowo w menu, które nazywamy getNewVideos:
var getNewVideos = function () {var page = 1; if (call == 'random') {// Ustaw stronę jako losową na 40 stronach Vimeo Staff Pickspage = Math.floor (Math.random () * 39) + 2;} var apiUrl = 'http://vimeo.com/api/rest/v2';var parameters = {metoda:' vimeo.channels.getVideos ', channel_id:' staffpicks ', per_page: numberOfVideosToDownload, page : page, full_response: 'true', format: 'jsonp', callback: 'Ext.util.JSONP.callback'}; Ext.util.JSONP.request ({url: getUrlWithSignature (apiUrl, parameters), callback: function ( odpowiedź) {handleNewVideos (odpowiedź);}});};
Jest to dość proste. Po podjęciu decyzji, którą stronę Staff Picks zażądać od Vimeo, wykonujemy wywołanie JSONP, korzystając z wbudowanej funkcji Senchy. W oddzwonieniu sprawdzamy, czy status jest w porządku, a następnie dzwonimy handleNewVideos.
var handleNewVideos = function (response) {if (response.stat == 'ok') {videos = response.videos.video; // Usuń bieżące videosvideoStore.removeAll (); // Powtarzaj filmy, tworząc nowe instancje modelu var instances = []; for (var i = 0, j = videos.length; ij; i ++) {var video = videos [i]; var instance = Ext.ModelMgr.create ({id: video.id, description: video.description , wysokość: video.height, dostępne: (video.urls.url.length> 1)? 'mobile': 'online', thumbnail_medium: video.thumbnails.thumbnail [1] ._ content, thumbnail_large: video.thumbnails.thumbnail [2] ._ content, title: video.title, username: video.owner.realname, width: video.width, watch: isVideoWatched (video.id)? 'Watched': ''}, 'Video', video. id); instances.push (instance);} // Wstaw nowe elementy do storevideoStore.add (instances); // Save StatesaveState ();} else {alert ('Przepraszamy, nie mogliśmy skontaktować się z Vimeo, aby uzyskać więcej filmy. Spróbuj ponownie później ... '); setSelectedMenuItem (stan); loading.hide ();}};
Kiedy otrzymujemy filmy z Vimeo, robimy trzy rzeczy:
1. Usuń istniejące filmy ze sklepu: videoStore.removeAll ()
2. Przejrzyj nagrania wideo i utwórz ich instancje, gotowe do użycia w sklepie
3. Dodaj nowe filmy do sklepu: videoStore.add (instancje)
Pamiętaj, że kiedy ładowaliśmy filmy z Lokalny magazyn do sklepu, odpalił Załaduj wydarzenie, z którego zadzwonił updateCarousel? To samo dzieje się tutaj, gdy dodajemy filmy do sklepu.
Plik Dodaj uruchamiane jest zdarzenie, które synchronizuje sklep (kopiuje nasze nowe filmy do Lokalny magazyn) i dzwoni updateCarousel.
Gotowe!
I to, moi przyjaciele, kończy pętlę. Po uruchomieniu aplikacja ładuje filmy z plików Lokalny magazyn i wyświetla je na stronach karuzeli, które możesz przeglądać.
Dotknięcie menu powoduje wywołanie Ajax dla nowych filmów, dodaje te filmy do sklepu, synchronizuje się z powrotem Lokalny magazyn następnie wyświetla je ponownie w karuzeli.
Nie rozmawialiśmy o oglądaniu filmu, ale znajduje się on w kodzie źródłowym, który można pobrać powyżej. Pobaw się kodem i zobacz, co możesz stworzyć. Powodzenia!
Możesz zagrać w ostateczną aplikację w całej okazałości na iPada, pobierając ją z App Store (wyszukaj „jeszcze jeden”). Mamy nadzieję, że spodoba Ci się spędzanie godzin na oglądaniu najlepszych filmów krótkometrażowych Vimeo. No dalej, jeszcze tylko jeden ...