Abbiamo già affrontato un bel po 'di questa serie, inclusa la navigazione. Tuttavia, Ionic fornisce alcuni componenti che forniscono funzionalità aggiuntive per la creazione di una navigazione più funzionale. In questo tutorial, aggiungiamo i componenti del menu laterale e delle schede nell'app e guardiamo anche ad alcuni servizi aggiuntivi per rendere più intelligente la navigazione della nostra app.
I file del progetto tutorial sono disponibili su GitHub. La premessa generale dell'app è che mostra alcune informazioni sulle strutture locali. In questo tutorial, aggiungiamo la possibilità di mostrare biblioteche, musei, parchi e ospedali. Attualmente, sta visualizzando solo le sedi di Chicago, che è qualcosa che risolviamo nel prossimo tutorial.
Puoi scaricare il progetto completato per questo tutorial da GitHub a. Se cloni il progetto, puoi anche programmare il codice usando Git ed eseguendo git checkout -b start
. L'ultimo esempio è disponibile anche per l'anteprima.
Tieni presente che ho rimosso la risoluzione dalla visualizzazione dei luoghi che avevamo nella terza parte di questa serie. Non voglio coprirlo in profondità, ma il controller carica i dati ora e semplifica la nostra navigazione.
Uno dei modelli di navigazione più comuni nelle app mobili è un menu laterale. Questo è un cassetto che scorre lateralmente ed espone i collegamenti di navigazione e forse altri contenuti, come lo stato di accesso corrente. Di progettazione, sono fuori dallo schermo e sono aperti da una sorta di pulsante, spesso l'icona dell'hamburger, anche se le persone non sono d'accordo sull'uso di quell'icona.
I menu laterali sono spesso in grado di essere aperti facendo scorrere il dito da un lato per aprirlo o scorrere verso l'alto per spingerlo chiuso. Questo può essere utile, ma a volte può intralciare altri gesti e dovresti tenere d'occhio i comportamenti contraddittori. Dovresti considerare il miglior uso di swiping tenendo presente l'intera visione e l'esperienza della tua app, e se c'è una preoccupazione puoi disabilitarla.
Ionic fornisce un paio di componenti che rendono banale la creazione di un menu laterale. Puoi creare fino a due menu laterali, uno a destra e uno a sinistra. Un menu laterale comprende diversi componenti, ionSideMenus
, ionSideMenu
, e ionSideMenuContent
.
Per vedere questo in azione, aggiorna www / index.html e impostare un menu laterale. Sostituirai il contenuto esistente con il codice sottostante, che aggiunge i componenti del menu laterale attorno al nostro codice esistente.
Civinfo
posti impostazioni Indietro
Per abilitare un menu laterale, iniziamo avvolgendo il contenuto della nostra app in ionSideMenus
. Permette a Ionic di coordinare il menu laterale e le aree di contenuto. Abbiamo quindi un ionSideMenu
con un lato = "sinistra"
attributo per indicare quale lato occupa.
Nel menu laterale, possiamo inserire qualsiasi contenuto desideriamo. In questo caso, e probabilmente lo scenario più comune, il contenuto è un ionHeaderBar
componente e un ionList
componente per rendere rispettivamente il titolo dell'app e un elenco di collegamenti. Non abbiamo ancora definito la vista delle impostazioni, quindi il collegamento non funzionerà per il momento. Si noti inoltre che il ionItem
i componenti hanno un menu vicino
attributo. Questo chiude automaticamente il menu laterale quando un utente fa clic sul collegamento, altrimenti rimane aperto.
Il ionSideMenuContent
componente è usato per contenere l'area del contenuto principale. Questa area di contenuto occupa l'intero schermo, ma questo componente aiuta solo il rendering del componente del menu laterale correttamente. Abbiamo anche usato il drag-content = "false"
attributo per disabilitare i gesti di trascinamento perché interferiscono con la lista e le schede di scorrimento.
Abbiamo anche aggiunto un nuovo pulsante alla barra di navigazione utilizzando ionNavButtons
. Questa è l'icona del menu laterale che appare in alto a destra come tre linee sovrapposte. Questo pulsante ha il menu ginocchiera = "sinistra"
attributo, che attiva il menu a sinistra per attivare quando selezionato.
Ora che il nostro menu laterale è attivo, lavoriamo sull'impostazione del prossimo componente di navigazione principale aggiungendo schede per la vista delle impostazioni.
Le schede sono un altro schema di navigazione comune per la navigazione di un'app. Le schede sono facili da capire perché le vediamo in così tanti tipi di interfacce, non solo per le app mobili.
Le schede possono essere stateful o stateless. Una scheda che visualizza il contenuto che non conserva una memoria di eventuali modifiche è senza stato mentre una scheda che mantiene uno stato in base all'interazione dell'utente è dichiarativa (ad esempio, persistendo un risultato di ricerca). Vediamo come costruire tabs stateful con Ionic in quanto sono più complessi e potenti.
Configurare le schede è abbastanza facile con ionTabs
e ionTab
componenti. Proprio come i menu laterali, puoi inserire tutti i componenti della scheda come desideri. Non c'è un limite rigido, ma trovo che il cinque sia un massimo salutare. Sui dispositivi più piccoli, troppe icone rendono difficile selezionare una scheda.
Stiamo andando a configurare le schede creando un paio di nuovi file. Per prima cosa, impostiamo il modello creando un nuovo file in www / views / impostazioni / settings.html. Aggiungi il seguente codice al nuovo file.
Il ionTabs
componente è usato per avvolgere l'interno ionTab
componenti. Esistono diverse classi in cui è possibile definire la modalità di visualizzazione delle schede, ad esempio l'inserimento di schede in alto o in basso, utilizzando icone con o senza titoli e altro ancora. Qui, abbiamo deciso di utilizzare le schede che hanno un titolo con l'icona in alto con la preimpostazione dei colori stabile.
Il ionTab
componente ha un numero di attributi che possono essere utilizzati per definire il suo comportamento. Supporta molte funzionalità, come la visualizzazione di un piccolo badge di notifica, il collegamento di schede a stati, il comportamento delle icone e altro ancora. Per le nostre schede, ognuna ha un titolo
, una classe di icone per quando la scheda è attiva (Icona-on
) o inattivo (icona-off
) e collegamenti a uno stato utilizzando ui-sref
.
All'interno di ogni scheda c'è un altro ionNavView
. Questo può sembrare fuori posto dal momento che ne abbiamo già uno ionNavView
istituito in index.html. Quello che stiamo facendo è dichiarare luoghi aggiuntivi che uno stato può essere reso, che può essere considerato come una vista da bambino.
Ogni scheda è in grado di avere una propria cronologia di navigazione, perché ciascuno ionNavView
è indipendente dagli altri. Ogni scheda ha anche un nome univoco, che tornerà utile per poter definire determinati stati in modo che appaiano nel nome ionNavView
.
Potresti aver notato che non c'è ionView
elemento in questa pagina ed è importante notare quando si utilizzano le schede stateful. Non è necessario quando lo usi ionTabs
in questo modo, solo se utilizzi le schede senza stato, la versione del componente CSS, ti servirà.
ora dobbiamo impostare alcuni stati aggiuntivi per rendere funzionale l'esempio. Crea un altro file su www / views / impostazioni / settings.js e aggiungere il seguente codice ad esso.
angular.module ('App') .config (function ($ stateProvider, $ urlRouterProvider) $ stateProvider.state ('settings', url: '/ settings', abstract: true, templateUrl: 'views / settings / settings. html ') .state (' settings.about ', url:' / about ', views: about: templateUrl:' views / settings / tab.about.html ') .state (' impostazioni. licenza ', url:' / license ', visualizzazioni: about: templateUrl:' views / settings / tab.license.html '. .state (' settings.preferences ', url:' / preferences ' , visualizzazioni: preferenze: controller: 'PreferencesController', controllerAs: 'vm', templateUrl: 'views / settings / tab.preferences.html'); $ urlRouterProvider.when ('/ settings', '/ settings / preferences ');) .controller (' PreferencesController ', function (Types) var vm = this; vm.types = Types;);
Puoi vedere che stiamo impostando diversi nuovi stati, ma questi appaiono diversi dagli altri stati che abbiamo definito finora. Il primo stato è uno stato astratto, che è essenzialmente uno stato che non può essere caricato direttamente da solo e ha figli. Questo ha senso per noi con l'interfaccia delle schede perché impostazioni
lo stato carica il modello dei componenti delle schede, ma gli utenti non sono mai solo sul componente delle schede. Stanno sempre visualizzando la scheda attiva, che contiene un altro stato. Quindi l'uso dell'estrazione ci dà questa capacità di collegarli correttamente.
Gli altri tre stati sono definiti come impostazioni. [nome]
. Questo ci permette di definire una relazione genitore-figlio tra questi stati, che riflette essenzialmente la relazione genitore-figlio del ionTabs
e ionTab
componenti. Questi stati utilizzano la proprietà view, che è un oggetto con una proprietà denominata per la vista da utilizzare.
Il nome che dai al tuo modello con ionNavView
dovrebbe corrispondere al nome della proprietà. Il valore di quella proprietà è quindi la stessa definizione di stato, senza il url
è stato dichiarato nel solito modo. Il url
segue anche la relazione genitore-figlio combinando i due. Quindi tutti questi stati figlio rendono simili / impostazioni / preferenze.
Devi aggiungere settings.js a index.html usando un altro tag script. Dopo averlo fatto, vedrai alcuni errori perché stiamo facendo riferimento a un numero di file che non abbiamo ancora creato. Finiamo con i nostri modelli di schede.
Dobbiamo creare tre. I primi due sono contenuti statici quindi non ho intenzione di esaminarli in dettaglio. Crea un file a www / views / impostazioni / tab.about.html e aggiungere il seguente contenuto ad esso.
Progetto su GitHub
Clicca per vedere il progetto
Licenza
Vedi la licenza completa
Questo contiene un modello che mostra alcune informazioni. Si collega al progetto GitHub e alla licenza. Questo è quello che sembra.
Crea un altro file su www / views / impostazioni / tab.license.html e aggiungere il seguente contenuto ad esso.
La licenza MIT (MIT)Copyright (c) 2016 Jeremy Wilken
L'autorizzazione è concessa, a titolo gratuito, a chiunque ottenga una copia di questo software e dei file di documentazione associati (il "Software"), per trattare il Software senza restrizioni, inclusi, senza limitazioni, i diritti di utilizzo, copia, modifica, fusione. , pubblicare, distribuire, concedere in licenza e / o vendere copie del Software e consentire alle persone a cui è fornito il Software di farlo, alle seguenti condizioni:
La suddetta nota sul copyright e questa nota di autorizzazione devono essere incluse in tutte le copie o parti sostanziali del Software.
IL SOFTWARE VIENE FORNITO "COSÌ COM'È", SENZA GARANZIE DI ALCUN TIPO, ESPRESSE O IMPLICITE, INCLUSE, A TITOLO ESEMPLIFICATIVO, LE GARANZIE DI COMMERCIABILITÀ, IDONEITÀ PER UN PARTICOLARE SCOPO E NON VIOLAZIONE. IN NESSUN CASO GLI AUTORI OI DETENTORI DEL COPYRIGHT SARANNO RITENUTI RESPONSABILI PER QUALSIASI RECLAMO, DANNO O ALTRO RESPONSABILITÀ, SIA IN UN ATTO DI CONTRATTO, TORT O ALTRO, DERIVANTE DA, FUORI O IN RELAZIONE AL SOFTWARE O ALL'UTILIZZO O ALTRI CONTRATTI NELL'AMBITO DEL SOFTWARE.
Questo contiene il contenuto della licenza (MIT) per questo codice. C'è una semplice carta per contenere il contenuto. Questo è quello che sembra.
Il modello finale contiene alcuni elementi del modulo. Lo esaminerò un po 'più in dettaglio. Crea un nuovo file su www / views / impostazioni / tab.preferences.html e aggiungere il seguente contenuto ad esso.
- Tipi di posizioni
- Type.type
Questa vista contiene un elenco di commutatori che mostra i quattro tipi di luoghi che l'app può visualizzare, museo, parco, biblioteca e ospedale. Ciascuna di queste voci di elenco consente di abilitare o disabilitare un tipo di luogo dall'elenco. Il pulsante di attivazione è un componente CSS. Abbiamo solo bisogno di utilizzare un input casella di controllo con questo markup specifico e la struttura della classe CSS per farli apparire come pulsanti di attivazione / disattivazione mobile.
Questa vista ha un controller dichiarato in settings.js, ma inietta a tipi
servizio che non abbiamo ancora creato. Lo risolveremo aggiungendo un nuovo servizio a www / js / app.js.
.factory ('Types', function () return [type: 'Park', enabled: true, type: 'Hospital', abilitato: true, type: 'Library', abilitato: true, tipo : 'Museum', abilitato: true];)
Questo servizio contiene una serie di tipi di luoghi. Ha una proprietà per il nome di ciascun tipo di luogo e se è abilitato o disabilitato. Usiamo la proprietà abilitata nel pulsante di attivazione / disattivazione ngModel
per tracciare lo stato se quel tipo dovrebbe essere visualizzato.
A questo punto, è possibile aprire il menu laterale e navigare fino al collegamento delle impostazioni. Sei in grado di vedere le due schede, le preferenze e circa. Nella scheda delle preferenze, puoi attivare o disattivare i tipi di luoghi.
Se vai alla scheda about, puoi selezionare la licenza per vedere come naviga verso un'altra rotta all'interno della scheda. Se passi da una scheda all'altra tra le preferenze e la scheda dopo aver visto la licenza, puoi vedere che la scheda ricorda che ti trovavi nello stato della licenza anche dopo che te ne sei andato, dimostrando la natura attenta di queste schede.
L'ultimo passaggio di questo tutorial è di aggiornare la vista dei luoghi per utilizzare il tipi
servizio per caricare solo i tipi di posti desiderati e utilizzare il servizio cronologia per gestire quando ricaricare o utilizzare la cache.
Per impostazione predefinita, Ionic memorizza nella cache le ultime 10 viste e le conserva in memoria. Molte app potrebbero non avere nemmeno più stati, il che significa che l'intera app potrebbe rimanere in memoria. Questo è utile perché significa che Ionic non deve rendere di nuovo la vista prima di navigare, il che accelera l'app.
Ciò può causare alcuni problemi comportamentali perché si potrebbe pensare che i propri stati ricarichino e reinizializzano sempre il controller ogni volta che si accede allo stato. Poiché solo 10 viste sono memorizzate nella cache, se hai 20 visualizzazioni, solo l'ultimo 10 sarà nella cache. Ciò significa che non puoi garantire che una vista sia nella cache o meno. Pertanto, si dovrebbe evitare di eseguire la logica di installazione nei controller al di fuori dei ganci del ciclo di vita. È inoltre possibile configurare le strategie di memorizzazione nella cache utilizzando il $ ionicConfigProvider
.
A volte è necessario esaminare la cronologia di navigazione dell'utente per determinare cosa fare. Ad esempio, in questa app, vogliamo mantenere l'elenco dei posti nella cache se l'utente tocca un luogo e poi torna all'elenco. Se aggiornassimo automaticamente l'elenco ad ogni visita, gli utenti potrebbero perdere il loro posto nell'elenco dopo averlo fatto scorrere e aver visualizzato un luogo.
D'altra parte, se un utente naviga alla pagina delle impostazioni e poi torna all'elenco delle posizioni, vogliamo aggiornare l'elenco poiché potrebbero aver cambiato i tipi di luoghi che desiderano visualizzare.
Useremo una combinazione degli eventi del ciclo di vita che abbiamo visto prima con il $ ionicHistory
servizio per aggiungere una logica che aiuterà a determinare quando lo stato dei luoghi dovrebbe ricaricare la lista. Vogliamo anche usare il tipi
servizio per aiutarci a caricare solo i tipi di luoghi che l'utente desidera vedere.
Aperto www / views / luoghi / places.js e aggiornarlo per abbinare il seguente codice. Abbiamo bisogno di cambiare il modo in cui i dati vengono caricati e utilizzare il $ ionicHistory
servizio per ispezionare la cronologia per determinare quando ricaricare.
angular.module ('App') .config (function ($ stateProvider) $ stateProvider.state ('places', url: '/ places', controller: 'PlacesController as vm', templateUrl: 'views / places / places .html ');) .controller (' PlacesController ', funzione ($ http, $ scope, $ ionicLoading, $ ionicHistory, Geolocation, Types) var vm = this; var base =' https: // civinfo-apis .herokuapp.com / civic / places? location = '+ Geolocation.geometry.location.lat +', '+ Geolocation.geometry.location.lng; var token = "; vm.canLoad = true; vm.places = [] ; vm.load = function load () $ ionicLoading.show (); var url = base; var query = []; angular.forEach (tipi, funzione (tipo) if (type.enabled === true) query.push (type.type.toLowerCase ());); url + = '& query =' + query.join ('|'); if (token) url + = '& token =' + token; $ http.get (url) .then (function handleResponse (response) vm.places = vm.places.concat (response.data.results); token = response.data.next_page_token; if (! response.data.next_page_token) vm.canLoad = false; $ scope. $ broadcast ( 'scroll.infiniteScrollComplete'); $ IonicLoading.hide (); ); ; $ scope. $ on ('$ ionicView.beforeEnter', function () var previous = $ ionicHistory.forwardView (); if (! previous || previous.stateName! = 'place') token = "; vm.canLoad = false; vm.places = []; vm.load ();););
Innanzitutto, abbiamo modificato il modo in cui l'URL viene creato affinché la nostra API cambi dal caricamento dei soli parchi al caricamento dei tipi richiesti. Se si confronta questo con la versione precedente, viene utilizzato principalmente angular.forEach
per scorrere su ogni tipo e aggiungerlo all'URL.
Abbiamo anche modificato il modo in cui il $ ionicLoading
il servizio si comporta Invece di eseguire immediatamente quando il controller viene eseguito inizialmente, lo attiviamo in qualsiasi momento vm.load ()
il metodo è chiamato. Questo è importante perché il controller verrà memorizzato nella cache e non ricaricherà i dati per impostazione predefinita.
Il più grande cambiamento è il $ ionicView.beforeEnter
gestore dell'evento del ciclo di vita. Questo evento si attiva prima che la vista diventi la prossima vista attiva e ci consente di eseguire alcune impostazioni. Noi usiamo il $ IonicHistory.forwardView ()
metodo per ottenere informazioni sull'ultima visualizzazione dell'utente.
Se è il primo carico, questo sarà vuoto, altrimenti restituirà alcuni dati sull'ultimo stato. Quindi controlliamo se lo stato precedente era lo stato del luogo e, in tal caso, usiamo l'elenco dei risultati memorizzati nella cache. Inoltre, poiché abbiamo meno di 10 stati, sappiamo che lo stato sarà sempre tenuto in memoria.
In caso contrario, ripristinerà i valori memorizzati nella cache e genererà un nuovo carico di dati. Ciò significa che ogni volta che torno alla visualizzazione dei luoghi dopo aver eseguito le impostazioni, ricaricherà i dati. A seconda della progettazione dell'app, è probabile che si desideri progettare regole condizionali diverse su come gestire la memorizzazione nella cache e il ricaricamento.
Il servizio di cronologia fornisce ulteriori informazioni, come l'intero stack cronologico, la possibilità di modificare la cronologia, i dettagli sullo stato corrente e altro. È possibile utilizzare questo servizio per mettere a punto l'esperienza durante la navigazione nell'app.
Faremo altre due piccole modifiche al nostro modello di luoghi. Aperto www / views / luoghi / places.html e cambia il titolo in Luoghi locali.
Successivamente, aggiorna il componente di scorrimento infinito con un altro attributo, immediato controllo
, per impedire al componente di scorrimento infinito di caricare i dati nello stesso momento in cui si verifica il caricamento iniziale. Questo essenzialmente aiuta a prevenire richieste duplicate per più dati.
A questo punto, abbiamo creato un'app piuttosto solida che ha una serie di funzionalità piuttosto interessanti. Concluderemo questa serie con un ultimo tutorial su Cordova e l'integrazione con alcune delle funzionalità del dispositivo, come l'accesso ai dati GPS.
La navigazione con Ionic inizia sempre con la dichiarazione di alcuni stati. Esponendo che la navigazione può essere eseguita in vari modi, come abbiamo visto in questo tutorial. Questo è ciò che abbiamo trattato in questo tutorial:
$ ionicHistory
servizio per ulteriori informazioni sulla cronologia di navigazione dell'app per personalizzare l'esperienza.