Il comando ionic start
che abbiamo utilizzato per creare il modello di base della nostra applicazione prevede un parametro obbligatorio, il nome dell'applicazione, ed un parametro opzionale, il template da utilizzare o starter template. Il comando del nostro esempio era:
ionic start myApp
Esso indica che la nostra applicazione si chiamerà myApp
ma non specifica alcun parametro opzionale. In questo caso viene applicato un template di default tra quelli previsti da Ionic, come vedremo a breve.
Il template di un'applicazione è lo schema di partenza di un'applicazione, cioè un insieme di impostazioni che determinano il layout, la grafica ed eventuali funzionalità di base. Lo starter template
determina il contenuto della cartella www
nell'insieme delle cartelle di un progetto Ionic.
Allo stato attuale il framework prevede tre starter template predefiniti:
- blank;
- tabs (template di default);
- sidemenu.
Se non viene specificato un template, il comando ionic start
creerà un'applicazione a partire dal template tabs
. Analizziamo nel dettaglio ciascuno dei template predefiniti
Blank template
Il template blank
rappresenta un'applicazione senza un layout predefinito. Dopo aver creato un progetto Ionic di questo tipo troveremo nella cartella www
un file index.html
con il seguente contenuto:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="starter">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Ionic Blank Starter</h1>
</ion-header-bar>
<ion-content></ion-content>
</ion-pane>
</body>
</html>
Analizzando il codice possiamo notare i riferimenti al foglio di stile di Ionic (lib/ionic/css/ionic.css
) e ad un foglio di stile locale (css/style.css
) per eventuali ridefinizioni di impostazioni CSS.
Troviamo quindi il riferimento alla libreria di Ionic che include anche AngularJS:
<script src="lib/ionic/js/ionic.bundle.js"></script>
Oltra al riferimento alla libreria di Cordova troviamo anche il riferimento al codice JavaScript che definisce la nostra applicazione (js/app.js
).
Il markup della pagina contiene la direttiva Angular ng-app
associata al body, definendo quindi il contesto di esecuzione del framework. All'interno del body troviamo la direttiva ion-pane che rappresenta un contenitore generico all'interno del quale troviamo una intestazione (direttiva ion-header) e un'area per il contenuto (direttiva ion-content).
Il contenuto del file app.js
è anch'esso abbastanza semplice. In esso viene definita l'applicazione AngularJS starter
con l'esecuzione di alcune inizializzazioni:
angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
L'inizializzazione standard effettuata all'avvio dell'applicazione riguarda l'inibizione della visualizzazione della barra accessoria sulla tastiera virtuale.
Possiamo notare l'injection del servizio $ionicPlatform che mette a disposizione alcune funzioni di utilità, compreso il metodo ready() che fa da wrapper all'omonimo metodo di Cordova per eseguire del codice quando tutta l'infrastruttura è stata caricata.
Come possiamo vedere, lo starter template blank presenta semplicemente una struttura di base che non ha nessuna resa grafica. Gli altri due invece predispongono l'applicazione con due dei layout grafici più comuni.
Tabs template
Il template tabs rappresenta un template con un layout a tab, come quello mostrato dalla seguente immagine:
Si tratta in pratica di un layout con una serie di icone in basso che determinano le view da mostrare e una intestazione che consente la navigazione tra le view. Se diamo un'occhiata al markup della pagina index.html
vedremo che la parte rilevante, rispetto al template blank, è quella mostrata di seguito:
<!DOCTYPE html>
<html>
<head>
<!-- ... -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="starter">
<ion-nav-bar class="bar-stable">
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</body>
</html>
Oltre ad includere un riferimento al file app.js
, abbiamo un riferimento ai file controllers.js
e services.js
che conterranno rispettivamente i controller e i servizi Angular dell'applicazione.
Possiamo notare che il markup della pagina è costituito dalla direttiva ion-nav-bar che definisce la barra di navigazione superiore, all'interno della quale viene visualizzato il pulsante per la navigazione tra le view (direttiva ion-nav-back-button
) e dalla direttiva ion-nav-view che definisce la view all'interno della quale saranno caricati i template Angular presenti nalla cartella templates
.
Ciascun file della cartella templates
definisce il markup da visualizzare nella view principale tramite le direttive ion-view e ion-content come nel seguente esempio:
<ion-view view-title="Dashboard">
<ion-content class="padding">
...
</ion-content>
</ion-view>
Lasciamo al lettore l'analisi del markup di ciascun template e del relativo codice Angular, evidenziando invece il codice contenuto in app.js
che mette in relazione la view principale e i template
:
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])
.run(function($ionicPlatform) {
...
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
.state('tab.dash', {
url: '/dash',
views: {
'tab-dash': {
templateUrl: 'templates/tab-dash.html',
controller: 'DashCtrl'
}
}
})
...
.state('tab.account', {
url: '/account',
views: {
'tab-account': {
templateUrl: 'templates/tab-account.html',
controller: 'AccountCtrl'
}
}
});
$urlRouterProvider.otherwise('/tab/dash');
});
Notiamo in questo caso come, oltre all'inizializzazione tramite il metodo run()
di AngularJS, facciamo ricorso al metodo config() per definire il routing tra i template da visualizzare nella view principale.
Come possiamo vedere, Ionic non utilizza il servizio di routing di AngularJS ngRoute ma UI-Router, un modulo del progetto AngularUI.
UI-Router consente di definire il passaggio tra una schermata e l'altra di un'applicazione come le transizioni di una macchina a stati. Quindi, la visualizzazione di un template all'interno di una view rappresenta un particolare stato dell'applicazione. Inoltre, UI-Router
supporta view multiple nella stessa pagina e view annidate, caratteristiche non supportate dal routing predefinito di Angular.
Tornando al nostro codice vediamo che ciascuno stato, cioè ciascuna schermata della nostra applicazione, viene definito tramite il metodo state() del servizio $stateProvider
. Ogni stato ha un nome, rappresentato dalla stringa passata come primo parametro, e da una serie di impostazioni rappresentati dall'oggetto passato come secondo parametro.
Senza entrare nel dettaglio, le impostazioni di uno stato mappano essenzialmente un URL ad un template ed al rispettivo controller.
La struttura delle view della nostra applicazione fa uso delle view annidate di UI-Router con la view tab
come view di più alto livello:
$stateProvider.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
Essa disegna le icone in basso della nostra applicazione ed essendo definita come astratta viene attivata quando una qualsiasi delle view contenute in essa viene visualizzata.
Infine, in assenza di uno stato esplicito o valido, lo stato predefinito è individuato dall'URL /tab/dash
, corrispondente allo stato tab.dash
:
$urlRouterProvider.otherwise('/tab/dash');
Sidemenu template
Lo starter template sidemenu indica un template con un menu a scomparsa, come nel seguente esempio:
Come per il template tabs
, anche in questo caso la parte rilevante del markup contenuto nel file index.html
è molto sintetica:
<!DOCTYPE html>
<html>
<head>
...
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
</head>
<body ng-app="starter">
<ion-nav-view></ion-nav-view>
</body>
</html>
Esso si limita sostanzialmente ad indicare che il body
della pagina è a disposizione per la visualizzazione delle view dell'applicazione.
Nella cartella templates
, al solito, abbiamo il markup che definisce i singoli template da visualizzare all'interno della vista principale e in app.js
abbiamo l'inizializzazione e la mappatura tra view, template e controller:
angular.module('starter', ['ionic', 'starter.controllers'])
.run(function($ionicPlatform) {
...
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
.state('app.search', {
url: '/search',
views: {
'menuContent': {
templateUrl: 'templates/search.html'
}
}
})
...
.state('app.single', {
url: '/playlists/:playlistId',
views: {
'menuContent': {
templateUrl: 'templates/playlist.html',
controller: 'PlaylistCtrl'
}
}
});
$urlRouterProvider.otherwise('/app/playlists');
});
Sostanzialmente la struttura del codice non è molto diversa da quella del template tabs
.
Per il momento ci basta sapere a grandi linee la struttura generale del codice dei template predefiniti di Ionic, senza entrare nel dettaglio specifico del markup e del codice. Avremo modo di approfondire più avanti quando descriveremo le principali direttive e servizi che ci consentono di creare applicazioni rapidamente e con una interfacca abbastanza simile a quella delle applicazioni native.
Custom template
Oltre agli starter template predefiniti è possibile creare un'applicazione partendo da uno starter template personalizzato. È sufficiente in questo caso specificare il percorso assoluto o relativo sul file system della cartella contenente il template, come mostrato nel seguente esempio:
ionic start myApp ../ionicTemplates/myTemplate
In alternativa è possibile indicare l'URL da cui è possibile scaricare il template:
ionic start myApp http://www.mydomain.com/ionictemplates/myTemplate
A questo proposito segnaliamo un repository di starter template su CodePen da cui è possibile scaricare quello desiderato. Ad esempio, se intendiamo utilizzare il template Sign-in, then Tabs
che visualizza una schemata di login prima di passare ad un layout a tab, lanceremo il comando seguente:
ionic start myApp http://codepen.io/ionic/pen/CbBsA
All'avvio dell'applicazione verrà visualizzata una schermata analoga alla seguente:
Su GitHub sono inoltre disponibili diversi altri starter templates realizzati da vari autori.
Link utili