Questo tutorial ti guiderà attraverso lo sviluppo di un sito web mobile basato sulla posizione utilizzando il motore di ricerca di Google Place e Sencha Touch 2.1. Questo è un tutorial in due parti e in questa prima parte impareremo come creare un progetto con Sencha cmd, creare un tema interessante usando SASS / Compass e trovare servizi vicino alla posizione dell'utente.
Google fornisce un set di API per la ricerca di diversi servizi per tipo e posizione dell'utente. Al momento, Google supporta un totale di 96 tipi di servizio. Ci sono altri 30 servizi che possono essere recuperati solo tramite la ricerca. Google ha una lista completa di loro.
Per accedere all'API Places, l'obiettivo principale è registrare l'applicazione nella console dell'API di Google. Una volta che ci autenticiamo, otterremo una chiave API che è richiesta per ogni richiesta API. Google ha una guida passo passo.
L'API di Google Places utilizza una chiave API per identificare la tua applicazione. Le chiavi API sono gestite tramite la console delle API di Google. Avrai bisogno della tua chiave API prima di poter iniziare a utilizzare l'API. Per attivare l'API Places e creare la tua chiave:
Suppongo che tu abbia un server locale e che l'installazione di Sencha sia completata. In caso contrario, consultare la documentazione dettagliata qui con tutti i passaggi. Generiamo l'app Locator usando questo comando all'interno del nostro server locale.
sencha -sdk / path / to / sdk genera l'app Locator c: / xampp / htdocs / locator
Una volta terminato, apriremo l'app nel browser con l'url http: // localhost / locator e vedere un'applicazione di tabulazione di base.
Ora abbiamo bisogno di strutturare l'app con i componenti MVC.
Controller
Visualizzazioni
I negozi
Modelli
Un'applicazione Sencha può avere più file di controller. Tuttavia, per una piccola applicazione come questa, un controller andrà bene. Manterremo tutti i collegamenti dell'evento e le relative funzionalità all'interno di questo controller.
Le viste rappresentano le pagine dell'applicazione.
Dal momento che abbiamo due liste, manteniamo due modelli: Categoria e Posto. Allo stesso modo, due storage categorie e posti sono necessari per recuperare e salvare i dati correlati. Abbiamo bisogno di aggiungere tutti questi dettagli dei componenti in app.js in modo che il motore Sencha possa caricarli all'avvio.
Ext.Loader.setPath ('Ext': 'touch / src', 'Locator': 'app'); Ext.application (name: 'Locator', richiede: ['Ext.MessageBox', 'Locator.util.Util'], visualizzazioni: ['Main', 'Categories', 'PlaceList'], controller: ['App '], modelli: [' Category ',' Place '], memorizza: [' Categories ',' Places '], icona: ' 57 ':' resources / icons / Icon.png ',' 72 ':' risorse /icons/Icon~ipad.png ',' 114 ':' resources/icons/[email protected] ',' 144 ':' resources/icons/[email protected] ', isIconPrecomposed: true, startupImage : '320x460': 'risorse / startup / 320x460.jpg', '640x920': 'risorse / startup / 640x920.png', '768x1004': 'risorse / startup / 768x1004.png', '748x1024': 'risorse /startup/748x1024.png ',' 1536x2008 ':' risorse / startup / 1536x2008.png ',' 1496x2048 ':' risorse / startup / 1496x2048.png ', lancia: function () // Distruggi l'elemento #appLoadingIndicator Ext.fly ('appLoadingIndicator'). Destroy (); // Inizializza la vista principale Ext.Viewport.add (Ext.create ('Locator.view.Main'));, onUpdated: function () Ext.Msg .confirm ("Application Update", "Questa applicazione è stata appena eseguita con successo aggiornato alla versione più recente. Ricarica ora? ", Function (buttonId) if (buttonId === 'yes') window.location.reload ();););
Per ogni applicazione, abbiamo bisogno di una serie di funzioni e proprietà comuni che verranno utilizzate in tutta l'applicazione. Creiamo una classe Util singleton per la stessa cosa e inseriamo il file sotto app / util / directory. Al momento non è necessario comprendere le funzioni di questo file. Continueremo a discutere queste funzioni mentre procediamo.
Ext.define ('Locator.util.Util', singleton: true, // Se le viste dell'applicazione avranno un'animazione mentre si cambia on = r not enablePageAnimations: true, // La posizione corrente dell'utente viene salvata qui userLocation: null, / / Google place api key API_KEY: 'AIzaSyBmbmtQnXfq22RJhJfitKao60wDgqrC5gA', // Tutti gli api urls api: (function () // var baseUrl = 'https://maps.googleapis.com/maps/api/place/'; var baseUrl = 'php / action.php'; return baseUrl: baseUrl, categorie: 'resources / data / categories.json', nearestPlaces: baseUrl + ", nearBySearch: 'nearbysearch', foto: 'foto', dettagli: 'dettagli' ) (), // Distruggi una vista Sencha destroyCmp: function (child, parent) parent = parent || Ext.Viewport; if (child) Ext.defer (function () parent.remove (child); , Locator.util.Util.animDuration);, // Mostra avviso messaggio generale showMsg: function (msg, titolo, cb, scope) if (msg) Ext.Msg.alert (title || 'Error' , msg.toString (), cb || function () , scope || window); restituisce questo;, // Animat e l'elemento attivo showActiveItem: function (parentPanel, childPanel, animation) animation = Ext.apply (tipo: 'slide', durata: LocatrConfig.amimationDuration, animazione || ); if (parentPanel && childPanel) if (this.enablePageAnimations && animation && animation.type) parentPanel.animateActiveItem (childPanel, animation); else parentPanel.setActiveItem (childPanel); restituisce questo; , // Mostra una finestra di caricamento su showLoading: function (panel, doShow, message) panel = panel || Ext.Viewport; if (panel) if (doShow) panel.setMasked (xtype: 'loadmask', messaggio: messaggio || 'Loading ...'); else panel.setMasked (false); restituisce questo; , // Capitalizza il primo carattere di ogni parola di una stringa inTitleCase: function (str) if (! Str) return "; return str.replace (/ \ w \ S * / g, function (txt) return txt.charAt (0) .toUpperCase () + txt.substr (1) .toLowerCase ();););
Abbiamo istituito il Principale view, che è il wrapper di tutte le viste. Noi usiamo Navigazione Visualizza per la stessa cosa, che è piuttosto utile per il layout semplice della carta e la gestione del pulsante indietro. Al momento del lancio, ha solo l'elenco delle categorie come figlio.
/ ** * Vista principale - titolare di tutte le visualizzazioni. * Layout della scheda di default per supportare più viste come elementi * / Ext.define ('Locator.view.Main', extend: 'Ext.NavigationView', xtype: 'main', config: cls: 'default- bg ', items: [xtype:' categories ']);
Ora l'installazione dell'applicazione è terminata. Abbiamo la chiave API di Google Places e siamo pronti per creare un elenco di tutti i tipi e mostrarlo nella home page. C'è un problema, però. Google non fornisce un'API per recuperare tutti questi tipi. Dobbiamo creare manualmente un file di dati che elenca tutti i tipi. Ho creato un jSON file chiamato categories.json elencando tutti i tipi disponibili e inseriteli nel Risorse / dati elenco.
Categorie: [type: "contabile", tipo : "aeroporto", tipo : "amusement_park", tipo : "acquario", tipo : "art_gallery", type: "atm" , type: "bakery", type: "banca", type: "bar", type: "beauty_salon", type: "bicycle_store", type: "BOOK_STORE", type: "bowling_alley", type: "bus_station", type: "cafe", type: "campeggio", type: "car_dealer", type: "car_rental", type : "car_repair", tipo : "car_wash", tipo : "casino", tipo : "cimitero", type: "chiesa", type: "city_hall", type:" clothing_store ", tipo :" convenience_store ", tipo :" tribunale ", tipo :" dentista ", type:" department_store ", type:" dottore ", type:" elettricista" , type: "electronics_store", type: "ambasciata", type: "stabilimento", type: "finanza", type: "fire_station", type: "fiorista", type: "cibo", type: "funeral_home", type: "furniture_store", type: "gas_station", type: "general_contractor", type: "grocery_or_supermarket", type : "palestra", type: "hair_care", tipo: "hardware_store", type: "salute", tipo: "hindu_temple", tipo: "home_goods_store", type : "Ospedale", tipo : "insurance_agency", tipo : "jewelry_store", type: "biancheria", type: "l'avvocato", type: "biblioteca", type:" liquor_store ", tipo :" local_government_office ", tipo :" fabbro ", tipo :" alloggio ", type:" meal_delivery ", type:" meal_takeaway ", type:" moschea" , type: "movie_rental", type: "movie_theater", type: "moving_company", type: "museo", type: "night_club", type: "pittore", type: "park", type: "parcheggio", type: "pet_store", type: "farmacia", type: "fisioterapista", type: "place_of_worship", type : "idraulico", tipo : "polizia", tipo : "post_office", tipo : "real_estate_agency", type: "ristorante", type: "roofing_contractor", type:" rv_park ", tipo :" scuola ", tipo :" shoe_store ", tipo :" shopping_mall ", type:" spa ", type:" stadio ", type:" stoccaggio" , type: "store", type: "subway_station", type: "sinagoga", type: "taxi_stand", type: "train_station", type: "travel_agency", type: "università", type: "veterinary_care", type: "zoo"]
Ext.define ('Locator.model.Category', extend: 'Ext.data.Model', config: campi: ["tipo", nome: "nome", tipo: "stringa", converti: funzione ( v, record) // Converte in title case e restituisce return Locator.util.Util.toTitleCase (record.get ('type'). split ('_'). join ("));," size " ]);
La proprietà "nome" di questo modello utilizza lo stesso valore "tipo" della categoria. Poiché la maggior parte dei tipi ha un "carattere di sottolineatura", questa funzione di conversione crea un valore omettendo "_" e convertendo la stringa in title case. Quindi, "travel_agency" diventa "Agenzia di viaggi"e lo salviamo sotto la proprietà name di questo modello.
Ext.define ('Locator.store.Categories', estensione: 'Ext.data.Store', config: modello: 'Locator.model.Category', autoLoad: true, sorter: 'name', grouper: groupFn : function (record) return record.get ('name') [0];, proxy: tipo: 'ajax', url: Locator.util.Util.api.categories, reader: type: 'json ', rootProperty:' categories ');
Carichiamo automaticamente lo store perché dovrebbe essere la prima richiesta nell'app. Utilizziamo una funzione di raggruppamento per un elenco raggruppato e ordiniamo in base al primo carattere di ciascun nome di servizio.
La visualizzazione per categoria è un elenco semplice. Utilizziamo la barra degli indici e le funzionalità raggruppate per accedere facilmente a tutti i tipi.
Ext.define ('Locator.view.Categories', extend: 'Ext.List', xtype: 'categories', config: cls: 'default-bg category-list', itemTpl: 'name', store : 'Categorie', raggruppate: true, indexBar: true, title: Lang.home);
L'elenco ha il seguente aspetto:
Possiamo aggiungere determinati set di variabili preesistenti per modificare il tema Sencha esistente e ottenere un nuovo aspetto. Quello che segue è il file SASS. Se non hai già configurato SASS, ti preghiamo di seguire questo post sul blog per una guida passo-passo.
// Definizioni dei colori di base $ base-color: # 333; $ gradiente di base: 'opaco'; $ active-color: # 36B8FF; // Stili della barra degli strumenti $ toolbar-base-color: # 444; // Elenca gli stili $ list-header-bg-color: # ABE2FF; @import 'sencha-touch / default / all'; // Puoi rimuovere uno dei seguenti moduli che // non usi per creare un file css più piccolo. @include sencha-panel; @include sencha-buttons; @include sencha-sheet; @ include il sencha-picker; @include sencha-tabs; @include sencha-toolbar; @include sencha-toolbar-forms; @include sencha-indexbar; @include sencha-list; @include sencha-layout; @include sencha-carousel; @include sencha-form; @include sencha-msgbox; @include sencha-loading-spinner; @include sencha-list-pullrefresh;
Modifichiamo il colore della barra degli strumenti e il colore dell'intestazione dell'elenco e aggiungiamo il mix-in del plug-in dell'elenco.
Dopo aver fatto clic su uno degli elementi della categoria, vorremmo visualizzare tutte le attività vicine alla posizione corrente dell'utente in quella categoria. Dobbiamo seguire questo insieme di compiti:
Possiamo utilizzare direttamente la funzione di geolocalizzazione del navigatore o utilizzare Sencha Ext.device.Geolocation. Salviamo la latitudine e la longitudine nel util istanza per uso futuro.
Ext.device.Geolocation.getCurrentPosition (success: function (position) me.util.userLocation = position.coords.latitude + ',' + position.coords.longitude;, failure: function () me.util. showMsg (Lang.locationRetrievalError););
L'API di Google Places non supporta ancora le richieste JSONP, quindi non saremo in grado di recuperare i dati direttamente dal lato client. Dobbiamo utilizzare un proxy del server per recuperare i dati. Questo problema può essere risolto usando PHP e cURL.
Il config il file contiene un numero di costanti. Impostiamo l'url dell'API di base, il tipo di output dei dati e i dettagli delle dimensioni dell'immagine.
define ("BASE_API_URL", "https://maps.googleapis.com/maps/api/place/"); define ("DATA_OUTPUT_TYPE", "json"); define ("IMAGE_MAX_HEIGHT", 500); define ("IMAGE_MAX_WIDTH", 500);
Questa è una classe PhP che contiene la funzionalità per la configurazione dell'URL, l'invio di richieste CURL e il recupero dei dati.
class Locatr / ** * Imposta l'url in base ai parametri passati * @return String Un url completo con tutte le stringhe di query * / private static function getFinalUrl () return html_entity_decode (BASE_API_URL. $ _ REQUEST ["action"]. " /".DATA_OUTPUT_TYPE. "?". $ _ SERVER ['QUERY_STRING']); / ** * Una funzione generica per inviare tutte le richieste CURL * @return String Response per quella richiesta cURL * / funzione statica privata sendCurlRequest () // Ottieni risorsa cURL $ curl = curl_init (); // Imposta alcune opzioni - stiamo passando in un useragent anche qui curl_setopt_array ($ curl, array (CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => self :: getFinalUrl (), CURLOPT_SSL_VERIFYPEER => false, CURLOPT_USERAGENT => 'Codex Sample cURL Request' )); // Invia la richiesta e salva la risposta a $ risp $ response = curl_exec ($ curl); // Chiudi richiesta per eliminare alcune risorse curl_close ($ curl); restituire $ risposta; / ** * Recupera tutti i luoghi vicini e un'immagine di ciascuno, se disponibile * @return String Restituisce tutte le posizioni in json * / public static function getNearBySearchLocations () try $ data = json_decode (self :: sendCurlRequest ()) ; $ item = ""; per ($ i = 0; $ i < count($data -> risultati); $ i ++) $ item = $ data -> results [$ i]; if (isset ($ item -> photos)) $ imageUrl = BASE_API_URL. "photo? photoreference =". $ item -> photos [0] -> photo_reference. "& Sensore = false & maxheight = 300 & maxwidth = 300 & key =" $ _ GET [ "chiave"].; $ data -> risultati [$ i] -> foto [0] -> url = $ imageUrl; restituisce json_encode ($ data); catch (Exception $ e) print "Error at getNearBySearchLocations:". $ e -> getMessage ();
Ecco la funzionalità di ciascun metodo in questa classe:
file_get_contents ()
metodo anche per ottenere i dati qui.Questo URL è costruito con il primo riferimento di immagine e passato con i dati di risposta per ogni luogo. Questo ci aiuta a mostrare almeno un'immagine disponibile per ogni azienda.
Questo file è appena usato per chiamare il getNearBySearchLocations funzione della classe Locator. Inviamo le richieste Ajax dal nostro lato client direttamente a questo file.
include_once 'config.php'; include_once 'Locatr.php'; $ action = $ _REQUEST ["action"]; if (! isset ($ action)) throw new Exception ("il parametro '' action 'non viene fornito"); switch ($ action) case "nearbysearch": stampa Locatr :: getNearBySearchLocations (); rompere;
Per l'elenco dei luoghi, abbiamo bisogno di un negozio e un modello simile all'elenco delle categorie.
Ext.define ('Locator.model.Place', extend: 'Ext.data.Model', config: fields: ["formatted_address", "geometry", "icon", "id", "name", " rating "," riferimento "," tipi "," vicinanze "," foto "]);
Ext.define ('Locator.store.Places', extend: 'Ext.data.Store', config: model: 'Locator.model.Place', proxy: tipo: 'ajax', url: Locator.util .Util.api.nearestPlaces, reader: type: 'json', rootProperty: 'results');
Fino ad ora, non avevamo bisogno di un controller per nessuna funzionalità perché l'elenco delle categorie veniva popolato automaticamente dal suo negozio. Ora abbiamo bisogno del controller per gestire gli eventi. Elencheremo tutti i componenti richiesti sotto la proprietà refs del controller.
ref: categoriesList: 'categories', main: 'main', placeList: 'placelist'
L'elenco clicca evento nei controlli:
control: categoriesList: itemtap: 'loadPlaces'
Quando si fa clic su una categoria, vogliamo mostrare l'elenco dei posti disponibili in quella categoria. Come discusso in precedenza, prima recupereremo la posizione attuale dell'utente e quindi, con latitudine e longitudine, invieremo una richiesta Ajax al file action.php. Il controller con il "loadPlaces"la funzione si presenta così:
Ext.define ('Locator.controller.App', extend: 'Ext.app.Controller', richiede: ['Ext.device.Geolocation', 'Ext.Map'], util: Locator.util.Util, config : refs: categoriesList: 'categories', main: 'main', placeList: 'placelist', control: categoriesList: itemtap: 'loadPlaces', / ** * Recupera tutti i posti per un particlur categoria * / loadPlaces: function (lista, indice, target, record) var me = this, loadPlaces = function () // Mostra la pagina di elenco dei luoghi me.showPlaceList (record); // Carica il negozio con la posizione dell'utente, radius, type e api key store.getProxy (). setExtraParams (location: me.util.userLocation, action: me.util.api.nearBySearch, raggio: me.util.defaultSearchRadius, sensore: false, chiave: me.util .API_KEY, tipi: record.get ('tipo')); store.load (funzione (record) me.util.showLoading (me.getPlaceList (), false););, store = Ext.getStore ('Luoghi'); // Se la posizione dell'utente non è già impostata, recuperala. // Altrimenti carica i luoghi per la posizione dell'utente salvato se (! Me.uti l.userLocation) Ext.device.Geolocation.getCurrentPosition (success: function (position) me.util.userLocation = position.coords.latitude + ',' + position.coords.longitude; loadPlaces (); , failure: function () me.util.showMsg (Lang.locationRetrievalError); ); else // Pulisci l'archivio se sono presenti dati precedenti store.removeAll (); loadPlaces (); , / ** * Mostra elenco posti * / showPlaceList: function (record) this.getMain (). Push (xtype: 'placelist', titolo: record.get ('nome')); );
Il PlaceList la vista è anche una lista semplice. Usiamo XTemplate qui per utilizzare alcune funzioni di filtro. Il getImage la funzione riceve l'immagine dell'azienda. Se l'immagine non è disponibile, restituisce l'icona per quella attività.
Ext.define ('Locator.view.PlaceList', extend: 'Ext.List', xtype: 'placelist', config: cls: 'default-bg placelist', store: 'Places', emptyText: Lang.placeList .emptyText, itemTpl: Ext.create ('Ext.XTemplate', '[this.getImage (valori)]', '','', // Restituisce l'immagine aziendale se disponibile. Altrimenti mostra l'icona disponibile per quell'impresa getImage: function (data) if (data.photos && data.photos.length> 0) return ''; ritorno 'nome','vicinanza',' valutazione: this.getRating ',''; , // Mostra una valutazione basata su stella. I dettagli funzionali sono forniti nella classe Util getRating: function (rating) return Locator.util.Util.getRating (rating); ));
Otteniamo un punteggio da zero a cinque per le aziende. Invece di mostrare il numero di valutazione, possiamo scrivere una semplice funzione per mostrare le valutazioni come stelle. Aggiungiamo il GetRating funzione al util file, che può essere utilizzato all'interno di queste funzioni del modello PlaceList:
Ci sono tre immagini: nessuna stella, mezza stella e stella intera. Il codice CSS è il seguente:
getRating: function (rating, max, hideRatingValue) if (rating! == undefined) var str = ''; rating = parseFloat (valutazione); max = max || 5; // Dividiamo la valutazione in una parte fino al valore massimo per (var i = 1; i < = max; i++) // For each 1 rating, add a full star if (i < = rating) str += ''; if (i> rating) // Se la valutazione della parte è un decimale compreso tra 0 e 1, aggiungi la mezza stella se (valutazione% 1! == 0 &&; (i - valutazione) < 1) str += ''; // Per il valore di valutazione di tutte le parti 0, non aggiungere altre stelle str + = ''; if (! hideRatingValue) str + = ''; ritorno str; restituisce Lang.noRating;'+ valutazione +''; str + = '
.ratings overflow: auto; .ratings div.star float: left; altezza: 14px; larghezza: 14px; dimensione di sfondo: 12px! importante; posizione di fondo: 50%; .ratings .full-star background: url (... /images/full_star.png) no-repeat; .ratings .half-star background: url (... /images/half_star.png) nessuna ripetizione; .ratings .no-star background: url (... /images/no_star.png) nessuna ripetizione; .ratings .value float: left; dimensione del font: 13px; font-weight: bold; margin-left: 5px;
Ecco la finale PlaceList vista.
/ ****************************** Lista dei luoghi ***************** ************* / .placelist.x - list - emptytext font - size: 14px; colore: #fff; imbottitura: 20px; .x - list.placelist.x - list - item.x - dock - horizontal border: 0! important; .x - list.placelist.x - list - item.item / * background: rgba (255, 255, 255, 0.8); font-size: 14px; padding: 8px; * / / * background: rgba (255, 255, 255, 0.8); * / background: -webkit - gradiente (lineare, sinistra in alto, in basso a sinistra, colore - stop (0%, #ffffff), colore - stop (47%, # f6f6f6), color-stop (100%, #ededed)); / * Chrome, Safari4 + * / background: -webkit - lineare - gradiente (in alto, #ffffff 0%, # f6f6f6 47%, #ededed 100%); / * Chrome10 +, Safari5.1 + * / font - dimensione: 14px; border - radius: 5px; imbottitura: 8px; - webkit - box - shadow: 0 0 10px 2px rgba (0, 0, 0, 0,6); riempimento - a destra: 82 px; .x - list.placelist.x - list - item.item.name font - weight: bold; margine: 3px 0 8px 0; .x - list.placelist.x - list - item.item.vicinity font - size: 12px; colore: # 222; margin-bottom: 10px; .x-list.placelist .x-list-item .item .rating .x-list.placelist .x-list-item .photo, .x-list.placelist .x-list-item .icon-wrapper posizione: assoluta; mostra: -webkit-box; -webkit-box-align: center; -webkit-box-pack: center; a destra: 25px; inizio: 6px; .x-list.placelist .x-list-item .photo img max-width: 75px; altezza massima: 63 px; bordo: 2px bianco solido; -webkit-box-shadow: 0 0 5px 0px rgba (0, 0, 0, 0,5); sfondo: nero; .x-list.placelist .x-list-item .icon-wrapper background: # 960000; bordo: 2px bianco solido; - webkit - box - shadow: 0 0 5px 0px rgba (0, 0, 0, 0.5); .x - list.placelist.x - list - item.icon width: 50px; altezza: 50 px; sfondo: bianco; - webkit - mask - image: url (http: //maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png); - webkit - mask - dimensione: 35px; - webkit - mask - repeat: no - repeat; - webkit - maschera - posizione: 50%; / ****************************** Elenco dei luoghi ENDS *************** *************** /E poiché stiamo usando uno sfondo scuro, dobbiamo cambiare un po 'il pull-to-refresh dei CSS. Quindi, aggiungi i seguenti css nel file locator.css:Possiamo aggiungere un plugin pull-to-refresh a questo elenco di posti. Basta aggiungere il codice qui sotto nel PlaceList array config.
plugin: [xclass: 'Ext.plugin.PullRefresh', pullRefreshText: Lang.placeList.pullToRefresh]
/ * Pull per aggiornare il plugin * / .x-list-pullrefresh color: #fff; .X-list-pullrefresh-freccia -webkit - maschera: Centro url (dati: image / png; Base64, iVBORw0KGgoAAAANSUhEUgAAACgAAAA8CAYAAAAUufjgAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAjFJREFUeNrsmU8oREEYwOexdtNuKBfFwdVhCyfuysnFiXISS + 1BLopyUpKLXETkRLaUi1LK3Q2lpPbiQLnIn03a / Hm + z86Ttv0zM ++ bfbOar36Hbad5v535Zp7v47iuy0wOpyoEHccRHV9L9NxPkUE / bhKCOKiOSPAdn69DsJ5I8E2HYA0QJRJ8Bb50CDYRCT7pEMQD0kwk + CByUFQEW4gE73UIhoA2IsFb4ENEMCQ5MdU1IxwygpT3oKNLMGyyYFVscdhusc8tDpu + xRG7xf95BW0O2kNiV1AgIvaQ2BzUJNgJNJYZGyUU7OG1cal4Bi68oqkDPszy2teEwJp5Cdyu / lZ1g8CwIYJ7wEF + 2YmrNw90Byx3BizgKhaqizEP1wg7CLLxCEzy / CtauMeBlQDyEfNuGrgU6SyM8F9SyVgHdmRaH6tAb4XkToEp2d4M5mOK0TWMigU2koa8vJMRZPxEb2ss2LEVPMpPLlMRxBgDZjQJLgNbxb6Uab9tAn3EcifAeKkBMoLY + j0GWonk7oB + lmsFkwhidAGHBPmIeTcAnJcbKCuIMQEs + hScAzZEBqoIYuzyFVCJI36lMJ2CDfxibZeUu + EX / 4uMIFP8ZyLejxkgK0hG5a8kP4IYSZbr1IuQVHmAX0HGX4VuGfZVJ6cQxPd1uoRcWqDW0SroFVzZAnJZ / h0LWhAjUUAw4XdSSsH8fExRTEgtGAOuOTETBb16Jk412e + bxOSwglYw6PgWYABvLk8P7zGJFwAAAABJRU5ErkJggg == ) no - ripeti; sfondo: #fff;
Eccolo:
Questa è la prima parte del tutorial. Abbiamo creato un elenco di servizi forniti dall'API di Google Places e quindi per un particolare servizio e abbiamo mostrato un elenco di tutti i luoghi nelle vicinanze. Nella prossima e ultima parte di questo tutorial, tratteremo le seguenti funzionalità:
Sencha è attualmente una delle più potenti librerie mobili basate su HTML5. Una volta impostato, sarai in grado di scrivere applicazioni mobili perfette e fluide. Queste applicazioni possono essere utilizzate come siti Web per dispositivi mobili o possono essere integrate in PhoneGap per creare app ibride iOS e Android.
La seconda parte di questo tutorial è ora disponibile. Scoprilo qui: Crea un sito che tenga conto della posizione con Sencha Touch - Visualizzazione delle posizioni.