SlideShare a Scribd company logo
1 of 85
Download to read offline
Costruire una app mobile con Ionic, 
AngularJS ed ovviamente Drupal
Chi sono
Chi sono 
Davide Michel Morelli 
michel@ziobuddalabs.it
Chi sono 
Davide Michel Morelli 
michel@ziobuddalabs.it 
Programmatore PHP Senior, Drupal Senior e DBA MySQL
Chi sono 
Davide Michel Morelli 
michel@ziobuddalabs.it 
Programmatore PHP Senior, Drupal Senior e DBA MySQL 
Sviluppatore Web AngularJS, MongoDB (da poco) e NodeJS
Chi sono 
Davide Michel Morelli 
michel@ziobuddalabs.it 
Programmatore PHP Senior, Drupal Senior e DBA MySQL 
Sviluppatore Web AngularJS, MongoDB (da poco) e NodeJS 
Sviluppatore Mobile su piattaforma HTML/CSS/JS
Iniziamo
Cos'è Drupal
Cos'è Drupal 
Veramente ??? No dai :D
Drupal: Services
Drupal: Services 
Si installa nel solito modo
Drupal: Services 
Si installa nel solito modo 
Si deve creare quello che si chiama Rest point
Drupal: Services 
Si installa nel solito modo 
Si deve creare quello che si chiama Rest point 
 Maggiore diversificazione delle risorse
Drupal: Services 
Si installa nel solito modo 
Si deve creare quello che si chiama Rest point 
 Maggiore diversificazione delle risorse 
 All'interno della configurazione di services si possono dare i 
permessi di accesso per i singoli servizi
Drupal: Services
Drupal: Services 
Si installa nel solito modo 
Si deve creare quello che si chiama Rest point 
 Maggiore diversificazione delle risorse 
 All'interno della configurazione di services si possono dare i permessi 
di accesso per i singoli servizi 
 Attenzione: i permessi per accedere alla funzionalità del servizio 
non sono i permessi di accesso di Drupal. 
Vanno configurati anche questi 
Altrimenti si avranno degli accessi negati senza capire il perché.
Drupal: Services 
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON 
Perché è la soluzioni più pratica.
Drupal: Services 
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON 
Perché è la soluzioni più pratica. 
Drupal può rispondere in 3 modi diversi
Drupal: Services 
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON 
Perché è la soluzioni più pratica. 
Drupal può rispondere in 3 modi diversi 
Creiamo la nostra funzione che risponde in JSON
Drupal: Services 
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON 
Perché è la soluzioni più pratica. 
Drupal può rispondere in 3 modi diversi 
Creiamo la nostra funzione che risponde in JSON 
Utilizziamo views_datasource che risponde in JSON
Drupal: Services 
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON 
Perché è la soluzioni più pratica. 
Drupal può rispondere in 3 modi diversi 
Creiamo la nostra funzione che risponde in JSON 
Utilizziamo views_datasource che risponde in JSON 
Utilizziamo Services che consente i CRUD
Drupal: Services 
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON 
Perché è la soluzioni più pratica. 
Drupal può rispondere in 3 modi diversi 
Creiamo la nostra funzione che risponde in JSON 
Utilizziamo views_datasource che risponde in JSON 
Utilizziamo Services che consente i CRUD 
In Drupal Services i nodi si possono creare chiamando direttamente 
il servizio /node
Drupal: Services 
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON 
Perché è la soluzioni più pratica. 
Drupal può rispondere in 3 modi diversi 
Creiamo la nostra funzione che risponde in JSON 
Utilizziamo views_datasource che risponde in JSON 
Utilizziamo Services che consente i CRUD 
In Drupal Services i nodi si possono creare chiamando direttamente 
il servizio /node 
La struttura deve essere come se lo stessi creando via PHP. 
Title, Type, Body sono valori normali (nessuno nota l'errore?) 
Un FIELD è invece nella struttura: { 'und' : [ { value: ILVALORE } ]} 
che corrisponde a [LANGUAGE_NONE][0][value]
Drupal: Services 
Attenzione nello sviluppo nella fase di debug: 
Access-Control-Allow-Origin 
(https://github.com/systemseed/services_accept_origin) 
Plugin per Chrome: 
“Allow-Control-Allow-Origin” 
Questo problema c'è solo sui browser perché sugli smartphone l'accesso 
avviene da file:// e non http:// 
Consiglio: 
Testare su un device fisico è sempre meglio. 
Si hanno le vere risposte delle performance e si può fare il debug 
dell'html tramite chrome://inspect
AngularJS
AngularJS 
E' un MVC
AngularJS 
E' un MVC 
O meglio un MVVM perché c'è il doppio binding
AngularJS 
E' un MVC 
O meglio un MVVM perché c'è il doppio binding 
Sviluppato da Google
AngularJS 
E' un MVC 
O meglio un MVVM perché c'è il doppio bindig 
Sviluppato da Google 
Permette di spostare la logica di funzionamento di un framework 
direttamente sul frontend
AngularJS 
E' un MVC 
O meglio un MVVM perché c'è il doppio bindig 
Sviluppato da Google 
Permette di spostare la logica di funzionamento di un framework 
direttamente sul frontend 
Pensato per creare SAP: Singe Application Page
AngularJS 
E' un MVC 
O meglio un MVVM perché c'è il doppio bindig 
Sviluppato da Google 
Permette di spostare la logica di funzionamento di un framework 
direttamente sul frontend 
Pensato per creare SAP: Singe Application Page 
Ma lo si può usare in tanti modi
IonicFramework
IonicFramework 
All'inizio c'erano le applicazioni che venivano create con il linguaggio 
dello smartphone
IonicFramework 
All'inizio c'erano le applicazioni che venivano create con il linguaggio 
dello smartphone 
Poi si è pensato di utilizzare il web per creare delle piccole pagine a 
modo di applicazione ed è stato inventato jQueryMobile
IonicFramework 
All'inizio c'erano le applicazioni che venivano create con il linguaggio 
dello smartphone 
Poi si è pensato di utilizzare il web per creare delle piccole pagine a 
modo di applicazione ed è stato inventato jQueryMobile 
Poi c'è stato Phonegap (diventato poi cordova, ma rimasto anche 
Phonegap) che ha permesso di creare delle specie di applicazioni 
native che sfruttano il browser
IonicFramework 
All'inizio c'erano le applicazioni che venivano create con il linguaggio 
dello smartphone 
Poi si è pensato di utilizzare il web per creare delle piccole pagine a 
modo di applicazione ed è stato inventato jQueryMobile 
Poi c'è stato Phonegap (diventato poi cordova, ma rimasto anche 
Phonegap) che ha permesso di creare delle specie di applicazioni 
native che sfruttano il browser 
Phonegap/Cordova fornisce solo l'accesso alla risorsa dello smartphone 
all'interno del browser 
Tastiera 
Vibrazione 
Fotocamera 
Filesystem 
Altro...
IonicFramework 
JqueryMobile ha però il concetto di unica pagina dove tutto deve essere 
visualizzato e poi nascosto
IonicFramework 
JqueryMobile ha pero' il concetto di unica pagina dove tutto deve essere 
visualizzato e poi nascosto 
Angular ha il concetto di “vista” che può essere riempita a seconda di 
quello che si vuole visualizzare
IonicFramework 
JqueryMobile ha pero' il concetto di unica pagina dove tutto deve essere 
visualizzato e poi nascosto 
Angular ha il concetto di “vista” che puo' essere riempita a secondo di 
quello che si vuole visualizzare 
Sullo smartphone (meno memoria, meno potenza di calcolo) è molto 
meglio visualizzare poco alla volta
IonicFramework 
JqueryMobile ha pero' il concetto di unica pagina dove tutto deve essere 
visualizzato e poi nascosto 
Angular ha il concetto di “vista” che puo' essere riempita a secondo di 
quello che si vuole visualizzare 
Sullo smartphone (meno memoria, meno potenza di calcolo) è molto 
meglio visualizzare poco alla volta 
Quindi come unire mobile, user interface e applicazioni native ?
IonicFramework 
IonicFramework prende Cordova e lo unisce ad Angular ampliandoli
IonicFramework 
IonicFramework prende Cordova e lo unisce ad Angular ampliandoli 
Accesso al dispositivo (cordova)
IonicFramework 
IonicFramework prende Cordova e lo unisce ad Angular ampliandoli 
Accesso al dispositivo (cordova) 
Gestione della visualizzazione, del reperimento dei dati (angularjs)
IonicFramework 
IonicFramework prende Cordova e lo unisce ad Angular ampliandoli 
Accesso al dispositivo (cordova) 
Gestione della visualizzazione, del reperimento dei dati (angularjs) 
Attività normali dello smartphone rese disponibili
IonicFramework 
Via JS 
Slide menu 
Tab 
Swipe 
Routing per le pagine interne 
Finestre modali 
Finestre di loading (spinner)
IonicFramework 
Via CSS 
Slides 
Lists 
Bottoni 
Header 
Footer
IonicFramework 
Come fare le chiamate con Ionic, o meglio via AngularJS: 
3 alternative praticabili 
$http 
$resource 
Restangular 
Sono messe in ordine di “livello di programmazione”. 
Dal più basso al più alto.
IonicFramework 
Per questo talk ho usato Restangular, anche se ci sono cose che non mi 
piacciono: 
Il risultato della chiamata viene restituito come oggetto 
Restangular 
Ma quello che abbiamo richiesto è messo allo stesso livello delle 
funzioni native. 
Quindi se riceviamo un array di informazioni non possiamo 
utilizzare angular.forEach() perché andremmo a prendere 
anche le funzioni native.
IonicFramework 
Per questo talk ho usato Restangular, anche se ci sono cose che non mi 
piacciono: 
Il risultato della chiamata viene restituito come oggetto Restangular 
Ma quello che abbiamo richiesto è messo allo stesso livello delle 
funzioni native. 
Quindi se riceviamo un array di informazioni non possiamo 
utilizzare angular.forEach() perché andremmo a prendere 
anche le funzioni native. 
Per usarlo con drupal è necessario modificarne il funzionamento 
(tramite apposita funzione addResponseInterceptor, nessuna modifica al 
codice di Restangular) perché Services ritorna una serie di oggetti, 
mentre Restangular vuole un elemento solo oppure un array.
IonicFramework 
Per questo talk ho usato Restangular, anche se ci sono cose che non mi 
piacciono: 
Il risultato della chiamata viene restituito come oggetto Restangular 
Ma quello che abbiamo richiesto è messo allo stesso livello delle 
funzioni native. 
Quindi se riceviamo un array di informazioni non possiamo 
utilizzare angular.forEach() perché andremmo a prendere 
anche le funzioni native. 
Per usarlo con drupal è necessario modificarne il funzionamento (tramite 
apposita funzione addResponseInterceptor, nessuna modifica al codice di 
Restangular) perché Services ritorna una serie di oggetti, mentre Restangular 
vuole un elemento solo oppure un array. 
Per un altro progetto ho usato $http. Meno funzioni evolute, ma più 
usabile
IonicFramework 
Vediamo come IonicFramework gestisce le varie “view”. 
Prima di tutto il file principale: INDEX.HTML
IonicFramework 
<!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>"Utrend"</title> 
<!-- build:css styles/vendor.css --> 
<!-- <link rel="stylesheet" href="vendor/some.contrib.css"> --> 
<!-- bower:css --> 
<link rel="stylesheet" href="lib/ionic/release/css/ionic.css" /> 
<!-- endbower --> 
<!-- endbuild --> 
<!-- build:css({.tmp,app}) styles/main.css --> 
<link rel="stylesheet" href="styles/main.css"> 
<!-- endbuild --> 
</head> 
<body ng-app="Utrend"> 
<ion-nav-view></ion-nav-view> 
<!-- build:js scripts/vendor.js --> 
<!-- <script src="vendor/someContribJs.js"></script> --> 
<!-- bower:js --> 
<script src="lib/angular/angular.js"></script> 
<script src="lib/angular-animate/angular-animate.js"></script> 
<script src="lib/angular-sanitize/angular-sanitize.js"></script> 
<script src="lib/angular-ui-router/release/angular-ui-router.js"></script> 
<script src="lib/collide/collide.js"></script> 
<script src="lib/ionic/release/js/ionic.js"></script> 
<script src="lib/ionic/release/js/ionic-angular.js"></script> 
<!-- endbower --> 
<!-- endbuild -->
IonicFramework 
<!-- cordova script (this will be a 404 during development) --> 
<script src="cordova.js"></script> 
<!-- build:js scripts/scripts.js --> 
<script src="scripts/common/angular-cookie.min.js"></script> 
<script src="scripts/common/underscore-min.js"></script> 
<script src="scripts/common/restangular.min.js"></script> 
<script src="scripts/config.js"></script> 
<script src="scripts/app.js"></script> 
<script src="scripts/controllers.js"></script> 
<script src="scripts/common/restfulServices.js"></script> 
<script src="scripts/common/sharedService.js"></script> 
<script src="scripts/user/loginCtrl.js"></script> 
<script src="lib/sweetalert/lib/sweet-alert.min.js"></script> 
<link rel="stylesheet" href="lib/sweetalert/lib/sweet-alert.css"> 
<script src="scripts/posts/picture.js"></script> 
<script src="scripts/posts/singlePostCtrl.js"></script> 
<script src="scripts/homeCtrl.js"></script> 
<!-- endbuild --> 
</body> 
</html> 
L'unico motivo per modificare questo file è per inserire i vari SCRIPT dei 
nostri controller
IonicFramework 
Ed il file che gestisce le view: app.js 
'use strict'; 
// Ionic Starter App, v0.9.20 
// angular.module is a global place for creating, registering and retrieving Angular modules 
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html) 
// the 2nd parameter is an array of 'requires' 
angular.module('Utrend', ['ionic', 'config', 'Utrend.controllers','restangular','ipCookie']) 
.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) { 
// org.apache.cordova.statusbar required 
StatusBar.styleDefault(); 
} 
}); 
})
IonicFramework 
Ed il file che gestisce le view: app.js 
.config(function($stateProvider, $urlRouterProvider,$compileProvider,RestangularProvider) { 
$stateProvider 
.state('app', { 
url: '/app', 
abstract: true, 
templateUrl: 'templates/menu.html', 
controller: 'AppCtrl' 
}) 
.state('app.home', { 
url: '/home', 
views: { 
'menuContent' :{ 
templateUrl: 'templates/home.html', 
controller : 'homeCtrl' 
} 
} 
}) 
.state('app.login', { 
url: '/login', 
controller: 'loginCtrl' 
}) 
})
IonicFramework 
Ed il file che gestisce le view: app.js 
.state('app.browse', { 
url: '/browse', 
views: { 
'menuContent' :{ 
templateUrl: 'templates/browse.html', 
controller: 'singlePostCtrl' 
} 
} 
}) 
.state('app.getPicture', { 
url: '/getpicture', 
views: { 
'menuContent' :{ 
templateUrl: 'templates/getPicture.html', 
controller: 'pictureCtrl' 
} 
} 
});
IonicFramework 
Ed il file che gestisce le view: app.js 
// if none of the above states are matched, use this as the fallback 
$urlRouterProvider.otherwise('/app/home'); 
$compileProvider.imgSrcSanitizationWhitelist(/^s*(https?|ftp|mailto|file|tel):/); 
RestangularProvider.setBaseUrl('http://MYDOMAIN/'); 
RestangularProvider.setResponseExtractor(function(response) { 
var newResponse = response; 
newResponse.originalElement = angular.copy(response); 
return newResponse; 
}); 
});
Drupal Service + IonicFramework 
Per collegarci a Drupal abbiamo detto che utilizzeremo Services
Drupal Service + IonicFramework 
Per collegarci a Drupal abbiamo detto che utilizzeremo Services 
Ma dobbiamo prestare attenzione ad una cosa molto importante: 
il token CSRF
Drupal Service + IonicFramework 
Per collegarci a Drupal abbiamo detto che utilizzeremo Services 
Ma dobbiamo prestare attenzione ad una cosa molto importante: 
Il token CSRF 
E' stato aggiunto dalla versione 3.5 del modulo services
Drupal Service + IonicFramework 
Per collegarci a Drupal abbiamo detto che utilizzeremo Services 
Ma dobbiamo prestare attenzione ad una cosa molto importante: 
Il token CSRF 
E' stato aggiunto dalla versione 3.5 del modulo services 
Lega a doppio mandato la sessione attuale con quella registrata sul server 
Per fare qualsiasi operazione che non sia un GET è richiesto questo 
TOKEN negli header della richiesta
Drupal Service + IonicFramework 
Per collegarci a Drupal abbiamo detto che utilizzeremo Services 
Ma dobbiamo prestare attenzione ad una cosa molto importante: 
Il token CSRF 
E' stato aggiunto dalla versione 3.5 del modulo services 
Lega a doppio mandato la sessione attuale con quella registrata sul server 
Per fare qualsiasi operazione che non sia un GET è richiesto questo 
TOKEN negli header della richiesta 
Per rendere il codice scritto più gestibile e leggibile è consigliabile 
creare un service di angular che gestisca per noi le connessioni
Drupal Service + IonicFramework 
(function () { 
angular.module('MyM').service('restfulService',['ipCookie','Restangular','$q',restfulService]); 
var tokenVar = ''; 
function restfulService(ipCookie,Restangular,$q) { 
//Qui le chiamate REST 
return { 
//Setta la directory di partenza del service rest. In questo modo non devo sempre definirlo 
restfulBase : function() { 
return Restangular.oneUrl('rest','http://MioDominio/rest'); 
}, 
} 
})();
Drupal Service + IonicFramework 
Prendiamo il token 
getToken : function(reset) { 
if (tokenVar != '' && !reset) { 
var deferred = $q.defer(); 
deferred.resolve(tokenVar); 
return deferred.promise 
} 
return 
Restangular.oneUrl('services/session/token','http://MIODOMINIO/services/session/token').get().then(function 
(token) { 
tokenVar = token; 
return token; 
}); 
}, 
Notate come non abbia utilizzato restfulBase ma solamente per una 
questione di demo
Drupal Service + IonicFramework 
E' facile creare una app che permetta di gestire gli utenti collegati e 
quelli non collegati (anonimi)
Drupal Service + IonicFramework 
E' facile creare una app che permetta di gestire gli utenti collegati e 
quelli non collegati (anonimi) 
Per farlo utilizzeremo AngularJS e il suo ng-if modificando il file di 
template del menù slide
Drupal Service + IonicFramework 
<ion-side-menus> 
<ion-pane ion-side-menu-content drag-content="false"> 
<ion-nav-bar class="bar-positive"> 
<!--<ion-nav-back-button class="button-clear"><i class="icon ion-ios7-arrow-back"></i> Back</ion-nav-back-button>--> 
</ion-nav-bar> 
<ion-nav-view name="menuContent" animation="slide-left-right"></ion-nav-view> 
</ion-pane> 
<ion-side-menu side="left"> 
<header class="bar bar-header bar-stable"> 
<h1 class="title">Left</h1> 
</header> 
<ion-content class="has-header"> 
<ion-list ng-if="user.uid == 0"> 
<ion-item nav-clear menu-close ng-controller="loginCtrl" ng-click="login()"> 
Login 
</ion-item> 
</ion-list>
Drupal Service + IonicFramework 
<ion-list ng-if="user.uid > 0"> 
<ion-item nav-clear menu-close > 
Hi, {{user.name}} 
</ion-item> 
<ion-item nav-clear menu-close > 
MyPage 
</ion-item> 
<ion-item nav-clear menu-close href="#/app/getpicture"> 
upload photo 
</ion-item> 
<ion-item nav-clear menu-close href="#/app/browse"> 
Browse 
</ion-item> 
<ion-item nav-clear menu-close href="#/app/search"> 
Search 
</ion-item> 
<ion-item nav-clear menu-close ng-controller="loginCtrl" ng-click="logout()"> 
Logout 
</ion-item> 
</ion-list> 
</ion-content> 
</ion-side-menu> 
</ion-side-menus>
Drupal Service + IonicFramework 
Vediamo il controller per il login (notate cosa usa) 
/** 
* Created by ziobudda on 05/11/14. 
*/ 
(function () { 
angular.module('Utrend').controller('loginCtrl', 
['$scope','$ionicModal','$state','sharedService','restfulService','$rootScope', loginCtrl]); 
function loginCtrl($scope, $ionicModal,$state,sharedService,restfulService,$rootScope) { 
$scope.error_message = ''; 
sharedService.getToken(); 
// Form data for the login modal 
$scope.loginData = {}; 
// Create the login modal that we will use later 
$ionicModal.fromTemplateUrl('templates/login.html', { 
scope: $scope 
}).then(function(modal) { 
$scope.modal = modal; 
}); 
// Triggered in the login modal to close it 
$scope.closeLogin = function() { 
$scope.modal.hide(); 
},
Drupal Service + IonicFramework 
// Open the login modal 
$scope.login = function() { 
$scope.modal.show(); 
}; 
// Perform the login action when the user submits the login form 
$scope.doLogin = function() { 
console.log('Doing login22', $scope.loginData); 
restfulService.login($scope.loginData) 
.then(function(result) { 
$rootScope.$broadcast("login",{user: result.user}); 
restfulService.getToken(true).then(function(result) { 
$scope.closeLogin(); 
swal({title: "Login OK", text: "Now you are a loggedin user!", type: "success"}); 
$state.go('app.browse') 
}) 
}, function (result) { 
$scope.error_message = result.data[0]; 
}); 
}
Drupal Service + IonicFramework 
$scope.logout = function () { 
restfulService.logout() 
.then(function(result) { 
sharedService.user = {}; 
sharedService.user.uid = 0; 
swal({title: "Logout OK", text: "Now you are a logged out user!", type: "success"}); 
$rootScope.$broadcast("logout"); 
$state.go("app.home"); 
}); 
} 
}; 
})();
Drupal Service + IonicFramework 
In questo controller abbiamo: 
Le finestre modali (per chiedere login e password)
Drupal Service + IonicFramework 
In questo controller abbiamo: 
Le finestre modali (per chiedere login e password) 
La gestione automatica del menù slide fatto tramite una semplice 
valorizzazione di sharedService.user
Drupal Service + IonicFramework 
E per visualizzare dei dati presi via GET ? Nella nostra app di prova sono 
delle immagini 
Il controller è puro AngularJS
Drupal Service + IonicFramework 
E per visualizzare dei dati presi via GET ? Nella nostra app di prova sono 
delle immagini 
Il controller è puro AngularJS 
Al div principale sono state definite le funzioni per gestire 
 swipe a sinistra 
 swipe a destra 
<div on-swipe-left="onSwipeLeft()" on-swipe-right="onSwipeRight()" > 
E' IonicFramework che rende facilmente disponibile il service 
$swipe di AngularJS 
https://docs.angularjs.org/api/ngTouch/service/$swipe
Drupal Service + IonicFramework 
Il codice HTML alla base della visualizzazione delle nostre immagini: 
<ion-view title="Browse"> 
<ion-nav-buttons side="left" class="bar-positive"> 
<button menu-toggle="left"class="button button-icon icon ion-android-contact"></button> 
</ion-nav-buttons> 
<ion-content class="has-header"> 
<div on-swipe-left="onSwipeLeft()" on-swipe-right="onSwipeRight()" > 
<div class="item item-body"> 
<img class="full-image" ng-src="{{post.fullimage}}"> 
<p> 
{{post.body.und[0].value}} 
</p> 
<p> 
<a href="#" class="subdued">{{post.like_count}} Like</a> 
<a href="#" class="subdued">{{post.comment_count}} Comments</a> 
</p> 
</div> 
<div class="item tabs tabs-secondary tabs-icon-left"> 
<a class="tab-item" href="#"> 
<i class="icon ion-thumbsup"></i> 
Like 
</a> 
<a class="tab-item" href="#"> 
<i class="icon ion-chatbox"></i> 
Comment 
</a> 
<a class="tab-item" href="#"> 
<i class="icon ion-share"></i> 
Share 
</a> 
</div> 
</div> 
</ion-content> 
</ion-view>
Drupal Service + IonicFramework 
E questo è il controller 
(function () { 
angular.module('Utrend').controller('singlePostCtrl', ['$scope','$ionicLoading', '$timeout', 'sharedService', 
'restfulService', '$rootScope', singlePostCtrl]); 
function singlePostCtrl($scope, $ionicLoading, $timeout, sharedService, restfulService, $rootScope) { 
$scope.searchParams = {from : sharedService.fromPost, limit : 1}; 
if (typeof $scope.post == 'undefined') { 
console.log("Azzero $scope.post"); 
$scope.post = {}; 
} 
$scope.getPost = function () { 
return restfulService.postSearch($scope.searchParams) 
.then(function(result) { 
sharedService.log("postSearch",result); 
return result; 
}) 
} 
//Questo prende il primo post quando viene instanziato questo controller 
restfulService.getToken().then(function (result) { 
$ionicLoading.show({template: '<i class="button-icon icon ion-loading-a"></i>'}); 
$scope.getPost().then(function (result) { 
$scope.post = result.value[0]; 
sharedService.log("post",$scope.post); 
$timeout(function() { 
$scope.$apply(); 
$ionicLoading.hide(); 
}); 
}); 
});
Drupal Service + IonicFramework 
$scope.onSwipeLeft = function() { 
console.log("onSwipeLeft"); 
$scope.searchParams.from++; 
sharedService.fromPost = $scope.searchParams.from; 
console.log($scope.searchParams.from); 
$ionicLoading.show({template: '<i class="button-icon icon ion-loading-a"></i>'}); 
$scope.getPost().then(function (result) { 
console.log("getToken -> getPost"); 
$scope.post = result.value[0]; 
sharedService.log("post",$scope.post); 
$timeout(function() { 
$scope.$apply(); 
$ionicLoading.hide(); 
}); 
}); 
}
Drupal Service + IonicFramework 
$scope.onSwipeRight = function() { 
console.log("onSwipeRight"); 
$scope.searchParams.from = ($scope.searchParams.from == 1) ? 0 : ($scope.searchParams.from-1); 
sharedService.fromPost = $scope.searchParams.from; 
console.log($scope.searchParams.from); 
$ionicLoading.show(); 
$scope.getPost().then(function (result) { 
console.log("getToken -> getPost"); 
$scope.post = result.value[0]; 
sharedService.log("post",$scope.post); 
$timeout(function() { 
$scope.$apply(); 
$ionicLoading.hide(); 
}); 
}); 
} 
} 
})();
Riassumendo 
Per creare applicazioni mobili che sfruttano l'html5: 
 AngularJS 
 IonicFramework (per velocizzare lo sviluppo) 
 Un servizio remoto che permetta di ricevere le informazioni da 
visualizzare in formato JSON
Domande ? 
Solo se conosco la risposta, per favore :D
Link utili 
AngularJS: https://angularjs.org/ 
IonicFramework: http://ionicframework.com/ 
IonicFramework Generator: https://github.com/diegonetto/generator-ionic 
La mia rivista flipboard dedicata ad angularJS e gli altri JS 
https://flipboard.com/section/angularjs%2C-nodejs-e-gli-altri-js-bTb8rt 
Icone per le app: http://ionicons.com/ 
Usare FontAwesome (Bootstrap): 
http://blog.nraboy.com/2014/10/ 
use-font-awesome-glyph-icons-ionicframework/
Grazie!
DrupalDay 2014: AngularJS + IonicFramework + Drupal Services

More Related Content

Similar to DrupalDay 2014: AngularJS + IonicFramework + Drupal Services

Ionic: Hybrid Mobile Apps... made simple
Ionic: Hybrid Mobile Apps... made simpleIonic: Hybrid Mobile Apps... made simple
Ionic: Hybrid Mobile Apps... made simpleCommit University
 
Workshop AngularJs, Cordova, Ionic - Politecnico di Milano
Workshop AngularJs, Cordova, Ionic - Politecnico di MilanoWorkshop AngularJs, Cordova, Ionic - Politecnico di Milano
Workshop AngularJs, Cordova, Ionic - Politecnico di MilanoGabriele Gaggi
 
Sviluppo di App cross-platform con Cordova e HTML5
Sviluppo di App cross-platform con Cordova e HTML5Sviluppo di App cross-platform con Cordova e HTML5
Sviluppo di App cross-platform con Cordova e HTML5Gabriele Gaggi
 
AngularJS – Reinventare le applicazioni web
AngularJS – Reinventare le applicazioni webAngularJS – Reinventare le applicazioni web
AngularJS – Reinventare le applicazioni webLuca Milan
 
Drupal Day 2012 - Applicazioni mobile multipiattaforma integrate con Drupal 7...
Drupal Day 2012 - Applicazioni mobile multipiattaforma integrate con Drupal 7...Drupal Day 2012 - Applicazioni mobile multipiattaforma integrate con Drupal 7...
Drupal Day 2012 - Applicazioni mobile multipiattaforma integrate con Drupal 7...DrupalDay
 
Angular js o React? Spunti e idee per la scelta di un framework
Angular js o React? Spunti e idee per la scelta di un frameworkAngular js o React? Spunti e idee per la scelta di un framework
Angular js o React? Spunti e idee per la scelta di un frameworkGiovanni Buffa
 
Angular in produzione: Best Practices e Performance Improvements
Angular in produzione:Best Practices e Performance ImprovementsAngular in produzione:Best Practices e Performance Improvements
Angular in produzione: Best Practices e Performance ImprovementsMichele Aponte
 
Federico Massi.it - Intro alle app mobile Cordova
Federico Massi.it - Intro alle app mobile CordovaFederico Massi.it - Intro alle app mobile Cordova
Federico Massi.it - Intro alle app mobile CordovaFederico Massi
 
Meet no Neet: presentazione del progetto App per organizzare eventi
Meet no Neet: presentazione del progetto App per organizzare eventiMeet no Neet: presentazione del progetto App per organizzare eventi
Meet no Neet: presentazione del progetto App per organizzare eventiFondazione Mondo Digitale
 
Applicazioni Web ultra-performanti con Vue.js e Delphi
Applicazioni Web ultra-performanti con Vue.js e DelphiApplicazioni Web ultra-performanti con Vue.js e Delphi
Applicazioni Web ultra-performanti con Vue.js e DelphiMarco Breveglieri
 
MOBILE APPS con ANDROID - Lo Stretto Digitale
MOBILE APPS con ANDROID  - Lo Stretto DigitaleMOBILE APPS con ANDROID  - Lo Stretto Digitale
MOBILE APPS con ANDROID - Lo Stretto Digitalelostrettodigitale
 
Strategie per applicazioni web prima o meglio dell'app nativa
Strategie per applicazioni web prima o meglio dell'app nativaStrategie per applicazioni web prima o meglio dell'app nativa
Strategie per applicazioni web prima o meglio dell'app nativaDiego La Monica
 
Introduzione alla localizzazione web
Introduzione alla localizzazione webIntroduzione alla localizzazione web
Introduzione alla localizzazione webQabiria
 
Multi-Device Hybrid Apps con Visual Studio e Apache Cordova
Multi-Device Hybrid Apps con Visual Studio e Apache CordovaMulti-Device Hybrid Apps con Visual Studio e Apache Cordova
Multi-Device Hybrid Apps con Visual Studio e Apache CordovaAndrea Dottor
 
Drupal Day 2011 - MobileD!
Drupal Day 2011 - MobileD!Drupal Day 2011 - MobileD!
Drupal Day 2011 - MobileD!DrupalDay
 

Similar to DrupalDay 2014: AngularJS + IonicFramework + Drupal Services (20)

Ionic: Hybrid Mobile Apps... made simple
Ionic: Hybrid Mobile Apps... made simpleIonic: Hybrid Mobile Apps... made simple
Ionic: Hybrid Mobile Apps... made simple
 
Workshop AngularJs, Cordova, Ionic - Politecnico di Milano
Workshop AngularJs, Cordova, Ionic - Politecnico di MilanoWorkshop AngularJs, Cordova, Ionic - Politecnico di Milano
Workshop AngularJs, Cordova, Ionic - Politecnico di Milano
 
Sviluppo di App cross-platform con Cordova e HTML5
Sviluppo di App cross-platform con Cordova e HTML5Sviluppo di App cross-platform con Cordova e HTML5
Sviluppo di App cross-platform con Cordova e HTML5
 
AngularJS – Reinventare le applicazioni web
AngularJS – Reinventare le applicazioni webAngularJS – Reinventare le applicazioni web
AngularJS – Reinventare le applicazioni web
 
Drupal Day 2012 - Applicazioni mobile multipiattaforma integrate con Drupal 7...
Drupal Day 2012 - Applicazioni mobile multipiattaforma integrate con Drupal 7...Drupal Day 2012 - Applicazioni mobile multipiattaforma integrate con Drupal 7...
Drupal Day 2012 - Applicazioni mobile multipiattaforma integrate con Drupal 7...
 
Angular js o React? Spunti e idee per la scelta di un framework
Angular js o React? Spunti e idee per la scelta di un frameworkAngular js o React? Spunti e idee per la scelta di un framework
Angular js o React? Spunti e idee per la scelta di un framework
 
Angular in produzione: Best Practices e Performance Improvements
Angular in produzione:Best Practices e Performance ImprovementsAngular in produzione:Best Practices e Performance Improvements
Angular in produzione: Best Practices e Performance Improvements
 
Federico Massi.it - Intro alle app mobile Cordova
Federico Massi.it - Intro alle app mobile CordovaFederico Massi.it - Intro alle app mobile Cordova
Federico Massi.it - Intro alle app mobile Cordova
 
Meet no Neet: presentazione del progetto App per organizzare eventi
Meet no Neet: presentazione del progetto App per organizzare eventiMeet no Neet: presentazione del progetto App per organizzare eventi
Meet no Neet: presentazione del progetto App per organizzare eventi
 
Applicazioni Web ultra-performanti con Vue.js e Delphi
Applicazioni Web ultra-performanti con Vue.js e DelphiApplicazioni Web ultra-performanti con Vue.js e Delphi
Applicazioni Web ultra-performanti con Vue.js e Delphi
 
Angular and beyond
Angular and beyondAngular and beyond
Angular and beyond
 
Node and the Cloud
Node and the CloudNode and the Cloud
Node and the Cloud
 
MOBILE APPS con ANDROID - Lo Stretto Digitale
MOBILE APPS con ANDROID  - Lo Stretto DigitaleMOBILE APPS con ANDROID  - Lo Stretto Digitale
MOBILE APPS con ANDROID - Lo Stretto Digitale
 
HTML5, il lato client della forza...
HTML5, il lato client della forza... HTML5, il lato client della forza...
HTML5, il lato client della forza...
 
AngularJS-Intro
AngularJS-IntroAngularJS-Intro
AngularJS-Intro
 
Strategie per applicazioni web prima o meglio dell'app nativa
Strategie per applicazioni web prima o meglio dell'app nativaStrategie per applicazioni web prima o meglio dell'app nativa
Strategie per applicazioni web prima o meglio dell'app nativa
 
Introduzione alla localizzazione web
Introduzione alla localizzazione webIntroduzione alla localizzazione web
Introduzione alla localizzazione web
 
Multi-Device Hybrid Apps con Visual Studio e Apache Cordova
Multi-Device Hybrid Apps con Visual Studio e Apache CordovaMulti-Device Hybrid Apps con Visual Studio e Apache Cordova
Multi-Device Hybrid Apps con Visual Studio e Apache Cordova
 
Drupal Day 2011 - MobileD!
Drupal Day 2011 - MobileD!Drupal Day 2011 - MobileD!
Drupal Day 2011 - MobileD!
 
WordPress REST API
WordPress REST APIWordPress REST API
WordPress REST API
 

DrupalDay 2014: AngularJS + IonicFramework + Drupal Services

  • 1.
  • 2. Costruire una app mobile con Ionic, AngularJS ed ovviamente Drupal
  • 4. Chi sono Davide Michel Morelli michel@ziobuddalabs.it
  • 5. Chi sono Davide Michel Morelli michel@ziobuddalabs.it Programmatore PHP Senior, Drupal Senior e DBA MySQL
  • 6. Chi sono Davide Michel Morelli michel@ziobuddalabs.it Programmatore PHP Senior, Drupal Senior e DBA MySQL Sviluppatore Web AngularJS, MongoDB (da poco) e NodeJS
  • 7. Chi sono Davide Michel Morelli michel@ziobuddalabs.it Programmatore PHP Senior, Drupal Senior e DBA MySQL Sviluppatore Web AngularJS, MongoDB (da poco) e NodeJS Sviluppatore Mobile su piattaforma HTML/CSS/JS
  • 10. Cos'è Drupal Veramente ??? No dai :D
  • 12. Drupal: Services Si installa nel solito modo
  • 13. Drupal: Services Si installa nel solito modo Si deve creare quello che si chiama Rest point
  • 14. Drupal: Services Si installa nel solito modo Si deve creare quello che si chiama Rest point  Maggiore diversificazione delle risorse
  • 15. Drupal: Services Si installa nel solito modo Si deve creare quello che si chiama Rest point  Maggiore diversificazione delle risorse  All'interno della configurazione di services si possono dare i permessi di accesso per i singoli servizi
  • 17. Drupal: Services Si installa nel solito modo Si deve creare quello che si chiama Rest point  Maggiore diversificazione delle risorse  All'interno della configurazione di services si possono dare i permessi di accesso per i singoli servizi  Attenzione: i permessi per accedere alla funzionalità del servizio non sono i permessi di accesso di Drupal. Vanno configurati anche questi Altrimenti si avranno degli accessi negati senza capire il perché.
  • 18. Drupal: Services Per le applicazioni mobili ci servono le chiamate che ritornino del JSON Perché è la soluzioni più pratica.
  • 19. Drupal: Services Per le applicazioni mobili ci servono le chiamate che ritornino del JSON Perché è la soluzioni più pratica. Drupal può rispondere in 3 modi diversi
  • 20. Drupal: Services Per le applicazioni mobili ci servono le chiamate che ritornino del JSON Perché è la soluzioni più pratica. Drupal può rispondere in 3 modi diversi Creiamo la nostra funzione che risponde in JSON
  • 21. Drupal: Services Per le applicazioni mobili ci servono le chiamate che ritornino del JSON Perché è la soluzioni più pratica. Drupal può rispondere in 3 modi diversi Creiamo la nostra funzione che risponde in JSON Utilizziamo views_datasource che risponde in JSON
  • 22. Drupal: Services Per le applicazioni mobili ci servono le chiamate che ritornino del JSON Perché è la soluzioni più pratica. Drupal può rispondere in 3 modi diversi Creiamo la nostra funzione che risponde in JSON Utilizziamo views_datasource che risponde in JSON Utilizziamo Services che consente i CRUD
  • 23. Drupal: Services Per le applicazioni mobili ci servono le chiamate che ritornino del JSON Perché è la soluzioni più pratica. Drupal può rispondere in 3 modi diversi Creiamo la nostra funzione che risponde in JSON Utilizziamo views_datasource che risponde in JSON Utilizziamo Services che consente i CRUD In Drupal Services i nodi si possono creare chiamando direttamente il servizio /node
  • 24. Drupal: Services Per le applicazioni mobili ci servono le chiamate che ritornino del JSON Perché è la soluzioni più pratica. Drupal può rispondere in 3 modi diversi Creiamo la nostra funzione che risponde in JSON Utilizziamo views_datasource che risponde in JSON Utilizziamo Services che consente i CRUD In Drupal Services i nodi si possono creare chiamando direttamente il servizio /node La struttura deve essere come se lo stessi creando via PHP. Title, Type, Body sono valori normali (nessuno nota l'errore?) Un FIELD è invece nella struttura: { 'und' : [ { value: ILVALORE } ]} che corrisponde a [LANGUAGE_NONE][0][value]
  • 25. Drupal: Services Attenzione nello sviluppo nella fase di debug: Access-Control-Allow-Origin (https://github.com/systemseed/services_accept_origin) Plugin per Chrome: “Allow-Control-Allow-Origin” Questo problema c'è solo sui browser perché sugli smartphone l'accesso avviene da file:// e non http:// Consiglio: Testare su un device fisico è sempre meglio. Si hanno le vere risposte delle performance e si può fare il debug dell'html tramite chrome://inspect
  • 28. AngularJS E' un MVC O meglio un MVVM perché c'è il doppio binding
  • 29. AngularJS E' un MVC O meglio un MVVM perché c'è il doppio binding Sviluppato da Google
  • 30. AngularJS E' un MVC O meglio un MVVM perché c'è il doppio bindig Sviluppato da Google Permette di spostare la logica di funzionamento di un framework direttamente sul frontend
  • 31. AngularJS E' un MVC O meglio un MVVM perché c'è il doppio bindig Sviluppato da Google Permette di spostare la logica di funzionamento di un framework direttamente sul frontend Pensato per creare SAP: Singe Application Page
  • 32. AngularJS E' un MVC O meglio un MVVM perché c'è il doppio bindig Sviluppato da Google Permette di spostare la logica di funzionamento di un framework direttamente sul frontend Pensato per creare SAP: Singe Application Page Ma lo si può usare in tanti modi
  • 34. IonicFramework All'inizio c'erano le applicazioni che venivano create con il linguaggio dello smartphone
  • 35. IonicFramework All'inizio c'erano le applicazioni che venivano create con il linguaggio dello smartphone Poi si è pensato di utilizzare il web per creare delle piccole pagine a modo di applicazione ed è stato inventato jQueryMobile
  • 36. IonicFramework All'inizio c'erano le applicazioni che venivano create con il linguaggio dello smartphone Poi si è pensato di utilizzare il web per creare delle piccole pagine a modo di applicazione ed è stato inventato jQueryMobile Poi c'è stato Phonegap (diventato poi cordova, ma rimasto anche Phonegap) che ha permesso di creare delle specie di applicazioni native che sfruttano il browser
  • 37. IonicFramework All'inizio c'erano le applicazioni che venivano create con il linguaggio dello smartphone Poi si è pensato di utilizzare il web per creare delle piccole pagine a modo di applicazione ed è stato inventato jQueryMobile Poi c'è stato Phonegap (diventato poi cordova, ma rimasto anche Phonegap) che ha permesso di creare delle specie di applicazioni native che sfruttano il browser Phonegap/Cordova fornisce solo l'accesso alla risorsa dello smartphone all'interno del browser Tastiera Vibrazione Fotocamera Filesystem Altro...
  • 38. IonicFramework JqueryMobile ha però il concetto di unica pagina dove tutto deve essere visualizzato e poi nascosto
  • 39. IonicFramework JqueryMobile ha pero' il concetto di unica pagina dove tutto deve essere visualizzato e poi nascosto Angular ha il concetto di “vista” che può essere riempita a seconda di quello che si vuole visualizzare
  • 40. IonicFramework JqueryMobile ha pero' il concetto di unica pagina dove tutto deve essere visualizzato e poi nascosto Angular ha il concetto di “vista” che puo' essere riempita a secondo di quello che si vuole visualizzare Sullo smartphone (meno memoria, meno potenza di calcolo) è molto meglio visualizzare poco alla volta
  • 41. IonicFramework JqueryMobile ha pero' il concetto di unica pagina dove tutto deve essere visualizzato e poi nascosto Angular ha il concetto di “vista” che puo' essere riempita a secondo di quello che si vuole visualizzare Sullo smartphone (meno memoria, meno potenza di calcolo) è molto meglio visualizzare poco alla volta Quindi come unire mobile, user interface e applicazioni native ?
  • 42. IonicFramework IonicFramework prende Cordova e lo unisce ad Angular ampliandoli
  • 43. IonicFramework IonicFramework prende Cordova e lo unisce ad Angular ampliandoli Accesso al dispositivo (cordova)
  • 44. IonicFramework IonicFramework prende Cordova e lo unisce ad Angular ampliandoli Accesso al dispositivo (cordova) Gestione della visualizzazione, del reperimento dei dati (angularjs)
  • 45. IonicFramework IonicFramework prende Cordova e lo unisce ad Angular ampliandoli Accesso al dispositivo (cordova) Gestione della visualizzazione, del reperimento dei dati (angularjs) Attività normali dello smartphone rese disponibili
  • 46. IonicFramework Via JS Slide menu Tab Swipe Routing per le pagine interne Finestre modali Finestre di loading (spinner)
  • 47. IonicFramework Via CSS Slides Lists Bottoni Header Footer
  • 48. IonicFramework Come fare le chiamate con Ionic, o meglio via AngularJS: 3 alternative praticabili $http $resource Restangular Sono messe in ordine di “livello di programmazione”. Dal più basso al più alto.
  • 49. IonicFramework Per questo talk ho usato Restangular, anche se ci sono cose che non mi piacciono: Il risultato della chiamata viene restituito come oggetto Restangular Ma quello che abbiamo richiesto è messo allo stesso livello delle funzioni native. Quindi se riceviamo un array di informazioni non possiamo utilizzare angular.forEach() perché andremmo a prendere anche le funzioni native.
  • 50. IonicFramework Per questo talk ho usato Restangular, anche se ci sono cose che non mi piacciono: Il risultato della chiamata viene restituito come oggetto Restangular Ma quello che abbiamo richiesto è messo allo stesso livello delle funzioni native. Quindi se riceviamo un array di informazioni non possiamo utilizzare angular.forEach() perché andremmo a prendere anche le funzioni native. Per usarlo con drupal è necessario modificarne il funzionamento (tramite apposita funzione addResponseInterceptor, nessuna modifica al codice di Restangular) perché Services ritorna una serie di oggetti, mentre Restangular vuole un elemento solo oppure un array.
  • 51. IonicFramework Per questo talk ho usato Restangular, anche se ci sono cose che non mi piacciono: Il risultato della chiamata viene restituito come oggetto Restangular Ma quello che abbiamo richiesto è messo allo stesso livello delle funzioni native. Quindi se riceviamo un array di informazioni non possiamo utilizzare angular.forEach() perché andremmo a prendere anche le funzioni native. Per usarlo con drupal è necessario modificarne il funzionamento (tramite apposita funzione addResponseInterceptor, nessuna modifica al codice di Restangular) perché Services ritorna una serie di oggetti, mentre Restangular vuole un elemento solo oppure un array. Per un altro progetto ho usato $http. Meno funzioni evolute, ma più usabile
  • 52. IonicFramework Vediamo come IonicFramework gestisce le varie “view”. Prima di tutto il file principale: INDEX.HTML
  • 53. IonicFramework <!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>"Utrend"</title> <!-- build:css styles/vendor.css --> <!-- <link rel="stylesheet" href="vendor/some.contrib.css"> --> <!-- bower:css --> <link rel="stylesheet" href="lib/ionic/release/css/ionic.css" /> <!-- endbower --> <!-- endbuild --> <!-- build:css({.tmp,app}) styles/main.css --> <link rel="stylesheet" href="styles/main.css"> <!-- endbuild --> </head> <body ng-app="Utrend"> <ion-nav-view></ion-nav-view> <!-- build:js scripts/vendor.js --> <!-- <script src="vendor/someContribJs.js"></script> --> <!-- bower:js --> <script src="lib/angular/angular.js"></script> <script src="lib/angular-animate/angular-animate.js"></script> <script src="lib/angular-sanitize/angular-sanitize.js"></script> <script src="lib/angular-ui-router/release/angular-ui-router.js"></script> <script src="lib/collide/collide.js"></script> <script src="lib/ionic/release/js/ionic.js"></script> <script src="lib/ionic/release/js/ionic-angular.js"></script> <!-- endbower --> <!-- endbuild -->
  • 54. IonicFramework <!-- cordova script (this will be a 404 during development) --> <script src="cordova.js"></script> <!-- build:js scripts/scripts.js --> <script src="scripts/common/angular-cookie.min.js"></script> <script src="scripts/common/underscore-min.js"></script> <script src="scripts/common/restangular.min.js"></script> <script src="scripts/config.js"></script> <script src="scripts/app.js"></script> <script src="scripts/controllers.js"></script> <script src="scripts/common/restfulServices.js"></script> <script src="scripts/common/sharedService.js"></script> <script src="scripts/user/loginCtrl.js"></script> <script src="lib/sweetalert/lib/sweet-alert.min.js"></script> <link rel="stylesheet" href="lib/sweetalert/lib/sweet-alert.css"> <script src="scripts/posts/picture.js"></script> <script src="scripts/posts/singlePostCtrl.js"></script> <script src="scripts/homeCtrl.js"></script> <!-- endbuild --> </body> </html> L'unico motivo per modificare questo file è per inserire i vari SCRIPT dei nostri controller
  • 55. IonicFramework Ed il file che gestisce le view: app.js 'use strict'; // Ionic Starter App, v0.9.20 // angular.module is a global place for creating, registering and retrieving Angular modules // 'starter' is the name of this angular module example (also set in a <body> attribute in index.html) // the 2nd parameter is an array of 'requires' angular.module('Utrend', ['ionic', 'config', 'Utrend.controllers','restangular','ipCookie']) .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) { // org.apache.cordova.statusbar required StatusBar.styleDefault(); } }); })
  • 56. IonicFramework Ed il file che gestisce le view: app.js .config(function($stateProvider, $urlRouterProvider,$compileProvider,RestangularProvider) { $stateProvider .state('app', { url: '/app', abstract: true, templateUrl: 'templates/menu.html', controller: 'AppCtrl' }) .state('app.home', { url: '/home', views: { 'menuContent' :{ templateUrl: 'templates/home.html', controller : 'homeCtrl' } } }) .state('app.login', { url: '/login', controller: 'loginCtrl' }) })
  • 57. IonicFramework Ed il file che gestisce le view: app.js .state('app.browse', { url: '/browse', views: { 'menuContent' :{ templateUrl: 'templates/browse.html', controller: 'singlePostCtrl' } } }) .state('app.getPicture', { url: '/getpicture', views: { 'menuContent' :{ templateUrl: 'templates/getPicture.html', controller: 'pictureCtrl' } } });
  • 58. IonicFramework Ed il file che gestisce le view: app.js // if none of the above states are matched, use this as the fallback $urlRouterProvider.otherwise('/app/home'); $compileProvider.imgSrcSanitizationWhitelist(/^s*(https?|ftp|mailto|file|tel):/); RestangularProvider.setBaseUrl('http://MYDOMAIN/'); RestangularProvider.setResponseExtractor(function(response) { var newResponse = response; newResponse.originalElement = angular.copy(response); return newResponse; }); });
  • 59. Drupal Service + IonicFramework Per collegarci a Drupal abbiamo detto che utilizzeremo Services
  • 60. Drupal Service + IonicFramework Per collegarci a Drupal abbiamo detto che utilizzeremo Services Ma dobbiamo prestare attenzione ad una cosa molto importante: il token CSRF
  • 61. Drupal Service + IonicFramework Per collegarci a Drupal abbiamo detto che utilizzeremo Services Ma dobbiamo prestare attenzione ad una cosa molto importante: Il token CSRF E' stato aggiunto dalla versione 3.5 del modulo services
  • 62. Drupal Service + IonicFramework Per collegarci a Drupal abbiamo detto che utilizzeremo Services Ma dobbiamo prestare attenzione ad una cosa molto importante: Il token CSRF E' stato aggiunto dalla versione 3.5 del modulo services Lega a doppio mandato la sessione attuale con quella registrata sul server Per fare qualsiasi operazione che non sia un GET è richiesto questo TOKEN negli header della richiesta
  • 63. Drupal Service + IonicFramework Per collegarci a Drupal abbiamo detto che utilizzeremo Services Ma dobbiamo prestare attenzione ad una cosa molto importante: Il token CSRF E' stato aggiunto dalla versione 3.5 del modulo services Lega a doppio mandato la sessione attuale con quella registrata sul server Per fare qualsiasi operazione che non sia un GET è richiesto questo TOKEN negli header della richiesta Per rendere il codice scritto più gestibile e leggibile è consigliabile creare un service di angular che gestisca per noi le connessioni
  • 64. Drupal Service + IonicFramework (function () { angular.module('MyM').service('restfulService',['ipCookie','Restangular','$q',restfulService]); var tokenVar = ''; function restfulService(ipCookie,Restangular,$q) { //Qui le chiamate REST return { //Setta la directory di partenza del service rest. In questo modo non devo sempre definirlo restfulBase : function() { return Restangular.oneUrl('rest','http://MioDominio/rest'); }, } })();
  • 65. Drupal Service + IonicFramework Prendiamo il token getToken : function(reset) { if (tokenVar != '' && !reset) { var deferred = $q.defer(); deferred.resolve(tokenVar); return deferred.promise } return Restangular.oneUrl('services/session/token','http://MIODOMINIO/services/session/token').get().then(function (token) { tokenVar = token; return token; }); }, Notate come non abbia utilizzato restfulBase ma solamente per una questione di demo
  • 66. Drupal Service + IonicFramework E' facile creare una app che permetta di gestire gli utenti collegati e quelli non collegati (anonimi)
  • 67. Drupal Service + IonicFramework E' facile creare una app che permetta di gestire gli utenti collegati e quelli non collegati (anonimi) Per farlo utilizzeremo AngularJS e il suo ng-if modificando il file di template del menù slide
  • 68. Drupal Service + IonicFramework <ion-side-menus> <ion-pane ion-side-menu-content drag-content="false"> <ion-nav-bar class="bar-positive"> <!--<ion-nav-back-button class="button-clear"><i class="icon ion-ios7-arrow-back"></i> Back</ion-nav-back-button>--> </ion-nav-bar> <ion-nav-view name="menuContent" animation="slide-left-right"></ion-nav-view> </ion-pane> <ion-side-menu side="left"> <header class="bar bar-header bar-stable"> <h1 class="title">Left</h1> </header> <ion-content class="has-header"> <ion-list ng-if="user.uid == 0"> <ion-item nav-clear menu-close ng-controller="loginCtrl" ng-click="login()"> Login </ion-item> </ion-list>
  • 69. Drupal Service + IonicFramework <ion-list ng-if="user.uid > 0"> <ion-item nav-clear menu-close > Hi, {{user.name}} </ion-item> <ion-item nav-clear menu-close > MyPage </ion-item> <ion-item nav-clear menu-close href="#/app/getpicture"> upload photo </ion-item> <ion-item nav-clear menu-close href="#/app/browse"> Browse </ion-item> <ion-item nav-clear menu-close href="#/app/search"> Search </ion-item> <ion-item nav-clear menu-close ng-controller="loginCtrl" ng-click="logout()"> Logout </ion-item> </ion-list> </ion-content> </ion-side-menu> </ion-side-menus>
  • 70. Drupal Service + IonicFramework Vediamo il controller per il login (notate cosa usa) /** * Created by ziobudda on 05/11/14. */ (function () { angular.module('Utrend').controller('loginCtrl', ['$scope','$ionicModal','$state','sharedService','restfulService','$rootScope', loginCtrl]); function loginCtrl($scope, $ionicModal,$state,sharedService,restfulService,$rootScope) { $scope.error_message = ''; sharedService.getToken(); // Form data for the login modal $scope.loginData = {}; // Create the login modal that we will use later $ionicModal.fromTemplateUrl('templates/login.html', { scope: $scope }).then(function(modal) { $scope.modal = modal; }); // Triggered in the login modal to close it $scope.closeLogin = function() { $scope.modal.hide(); },
  • 71. Drupal Service + IonicFramework // Open the login modal $scope.login = function() { $scope.modal.show(); }; // Perform the login action when the user submits the login form $scope.doLogin = function() { console.log('Doing login22', $scope.loginData); restfulService.login($scope.loginData) .then(function(result) { $rootScope.$broadcast("login",{user: result.user}); restfulService.getToken(true).then(function(result) { $scope.closeLogin(); swal({title: "Login OK", text: "Now you are a loggedin user!", type: "success"}); $state.go('app.browse') }) }, function (result) { $scope.error_message = result.data[0]; }); }
  • 72. Drupal Service + IonicFramework $scope.logout = function () { restfulService.logout() .then(function(result) { sharedService.user = {}; sharedService.user.uid = 0; swal({title: "Logout OK", text: "Now you are a logged out user!", type: "success"}); $rootScope.$broadcast("logout"); $state.go("app.home"); }); } }; })();
  • 73. Drupal Service + IonicFramework In questo controller abbiamo: Le finestre modali (per chiedere login e password)
  • 74. Drupal Service + IonicFramework In questo controller abbiamo: Le finestre modali (per chiedere login e password) La gestione automatica del menù slide fatto tramite una semplice valorizzazione di sharedService.user
  • 75. Drupal Service + IonicFramework E per visualizzare dei dati presi via GET ? Nella nostra app di prova sono delle immagini Il controller è puro AngularJS
  • 76. Drupal Service + IonicFramework E per visualizzare dei dati presi via GET ? Nella nostra app di prova sono delle immagini Il controller è puro AngularJS Al div principale sono state definite le funzioni per gestire  swipe a sinistra  swipe a destra <div on-swipe-left="onSwipeLeft()" on-swipe-right="onSwipeRight()" > E' IonicFramework che rende facilmente disponibile il service $swipe di AngularJS https://docs.angularjs.org/api/ngTouch/service/$swipe
  • 77. Drupal Service + IonicFramework Il codice HTML alla base della visualizzazione delle nostre immagini: <ion-view title="Browse"> <ion-nav-buttons side="left" class="bar-positive"> <button menu-toggle="left"class="button button-icon icon ion-android-contact"></button> </ion-nav-buttons> <ion-content class="has-header"> <div on-swipe-left="onSwipeLeft()" on-swipe-right="onSwipeRight()" > <div class="item item-body"> <img class="full-image" ng-src="{{post.fullimage}}"> <p> {{post.body.und[0].value}} </p> <p> <a href="#" class="subdued">{{post.like_count}} Like</a> <a href="#" class="subdued">{{post.comment_count}} Comments</a> </p> </div> <div class="item tabs tabs-secondary tabs-icon-left"> <a class="tab-item" href="#"> <i class="icon ion-thumbsup"></i> Like </a> <a class="tab-item" href="#"> <i class="icon ion-chatbox"></i> Comment </a> <a class="tab-item" href="#"> <i class="icon ion-share"></i> Share </a> </div> </div> </ion-content> </ion-view>
  • 78. Drupal Service + IonicFramework E questo è il controller (function () { angular.module('Utrend').controller('singlePostCtrl', ['$scope','$ionicLoading', '$timeout', 'sharedService', 'restfulService', '$rootScope', singlePostCtrl]); function singlePostCtrl($scope, $ionicLoading, $timeout, sharedService, restfulService, $rootScope) { $scope.searchParams = {from : sharedService.fromPost, limit : 1}; if (typeof $scope.post == 'undefined') { console.log("Azzero $scope.post"); $scope.post = {}; } $scope.getPost = function () { return restfulService.postSearch($scope.searchParams) .then(function(result) { sharedService.log("postSearch",result); return result; }) } //Questo prende il primo post quando viene instanziato questo controller restfulService.getToken().then(function (result) { $ionicLoading.show({template: '<i class="button-icon icon ion-loading-a"></i>'}); $scope.getPost().then(function (result) { $scope.post = result.value[0]; sharedService.log("post",$scope.post); $timeout(function() { $scope.$apply(); $ionicLoading.hide(); }); }); });
  • 79. Drupal Service + IonicFramework $scope.onSwipeLeft = function() { console.log("onSwipeLeft"); $scope.searchParams.from++; sharedService.fromPost = $scope.searchParams.from; console.log($scope.searchParams.from); $ionicLoading.show({template: '<i class="button-icon icon ion-loading-a"></i>'}); $scope.getPost().then(function (result) { console.log("getToken -> getPost"); $scope.post = result.value[0]; sharedService.log("post",$scope.post); $timeout(function() { $scope.$apply(); $ionicLoading.hide(); }); }); }
  • 80. Drupal Service + IonicFramework $scope.onSwipeRight = function() { console.log("onSwipeRight"); $scope.searchParams.from = ($scope.searchParams.from == 1) ? 0 : ($scope.searchParams.from-1); sharedService.fromPost = $scope.searchParams.from; console.log($scope.searchParams.from); $ionicLoading.show(); $scope.getPost().then(function (result) { console.log("getToken -> getPost"); $scope.post = result.value[0]; sharedService.log("post",$scope.post); $timeout(function() { $scope.$apply(); $ionicLoading.hide(); }); }); } } })();
  • 81. Riassumendo Per creare applicazioni mobili che sfruttano l'html5:  AngularJS  IonicFramework (per velocizzare lo sviluppo)  Un servizio remoto che permetta di ricevere le informazioni da visualizzare in formato JSON
  • 82. Domande ? Solo se conosco la risposta, per favore :D
  • 83. Link utili AngularJS: https://angularjs.org/ IonicFramework: http://ionicframework.com/ IonicFramework Generator: https://github.com/diegonetto/generator-ionic La mia rivista flipboard dedicata ad angularJS e gli altri JS https://flipboard.com/section/angularjs%2C-nodejs-e-gli-altri-js-bTb8rt Icone per le app: http://ionicons.com/ Usare FontAwesome (Bootstrap): http://blog.nraboy.com/2014/10/ use-font-awesome-glyph-icons-ionicframework/

Editor's Notes

  1. COVER
  2. LAST SLIDE