Desenvolvimento
Iniciando com aplicativos híbridos
Mobile







Palestrantes
Henrique Rotava
Mateus Nava
Rodrigo Rosa
Desenvolvedor
Compasso Tecnologia
Desenvolvedor
Inocode
Desenvolvedor
Wonder Sistemas



Roteiro
O que veremos hoje:
Introdução JavaScript
Framework AngularJS
Apache Cordova
Framework Ionic
Live coding

JavaScript
Brendan Eich - Netscape - 1995
Mocha > LiveScript > JavaScript
Porque Java?
Ecma (European Computer Manufacturers Association) Internacional

JS - ECMAScript
A especificação
Todo navegador executa JS?
JavaScript, JScript, ActionScript...
ES6 Mar-Jun 2015

Mundo JavaScript













JS - Toy language?
O princípio, enfeitando páginas
Só serve para fazer gambiarra?
Ela tem muitos bugs?
Não é orientada a objetos?

Muito flexível e interpretada.
JS - Tipagem Fraca
var type;
type = "It's a string!"; // Literal
type = 230; // Inteiro
type = 12.98 // Flutuante
type = [ 'first', 2, 32.7 ]; // Array
type = {
name : 'JavaScript',
birthDay : new Date(1995, 08, 15)
}; // Objeto
type = function(){
return typeof type;
}; // Função
JS - Blocos de repetição
for (var i = 0; i < 10; i++) {
console.log(i);
}
var cidades = ['Erechim', 'Passo Fundo', 'Marcelino Ramos'];
for (cidade in cidades) {
console.log(cidades[cidade]);
}
var x = 0;
while (x < 20) {
console.log(x);
x++;
}
JS - Estruturas de controle
var name = "kittens";
if (name == "puppies") {
name += "!";
} else if (name == "kittens") {
name += "!!";
} else {
name = "!" + name;
}
switch(action) {
case 'draw':
drawIt();
break;
case 'eat':
eatIt();
break;
default:
doNothing();
}
JS - Arrays
var names = new Array();
// or
var names = [];
names[0] = "John";
names[1] = "Mac";
names[2] = "Jean";
names.length; // 3
names[100] = "Julian";
names.length; // 101
names[90]; // undefined
names.push('Alan');
names.length; // 102
names.pop(); // "Alan"
names.length; // 101
JS - Objetos
var obj = new Object();
// or
var obj = {};
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
var samplePerson = new Person("Brendan", "Eich");
Person.prototype.fullName = function() {
return this.firstName + ' ' + this.lastName;
};
var fullName = samplePerson.fullName(); // "Brendan Eich"
var name = samplePerson.firstName; // "Brendan"
// or
var name = samplePerson['firstName']; // "Brendan"
JS - Funções
function add() {
var sum = 0;
for (var i = 0, j = arguments.length; i < j; i++) {
sum += arguments[i];
}
return sum;
}
add(2, 3, 4, 5); // 14
function add(x, y) {
var total = x + y;
return total;
}
add(2, 3); // 5
add(3, 1, 7) // 4; o 7 é ignorado
var a = 1;
var b = 2;
(function() {
var b = 3;
a += b;
})();
a; // 4
b; // 2
JS - Callbacks
function callCallBack(callback){
setTimeout(function(){
callback('Done!');
}, 1000);
}
callCallBack(function(message){
console.log(message);
});
console.log('Waiting...');
JS - Extras
// console
console.log('Debugando meu código no console.');
// alert()
alert('Este é um popup de alerta.');
// localStorage
localStorage.setItem('chave', 'valor');
localStorage.getItem('chave');
// JSON
JSON.parse('{"name": "Jhon", "age": "27"}');
JSON.stringify({name: "Jhon", age: "27"})
AngularJS
Executa no browser
Separação lógica, alta abstração
Customização de componentes HTML
by Google

Completo para CRUDs
Framework front-end web - MVC
[Help] Ionic Playground

Angular - Data Binding
Model <-> View
Sincronização automática
<div ng-app ng-init="qty=1;cost=2">
<b>Invoice:</b>
<div>
Quantity: <input type="number" min="0" ng-model="qty">
</div>
<div>
Costs: <input type="number" min="0" ng-model="cost">
</div>
<div>
<b>Total:</b> {{qty * cost | currency}}
</div>
</div>
Angular - Controllers
Diretiva ng-controller
Escopo $scope
Lógica de negócio de uma view
Não deve alterar o DOM
Model
View
Controller
User
Manipula
Atualiza
Visualiza
Usa
Angular - Controllers
var app = angular.module('app',[]);
app.controller('MainController', ['$scope', function($scope) {
$scope.num = 0;
$scope.title = 'Este é o título principal';
$scope.double = function(value) {
return value * 2;
};
$scope.reset = function(){
$scope.num = 0;
};
}]);
<body ng-app="app">
<div ng-controller="MainController">
<h1>{{ title }}</h1>
<br/>
O dobro de <input ng-model="num"> é {{ double(num) }}
<br/>
<button ng-click="reset()">Reiniciar</button>
</div>
</body>
JS
HTML
Angular - Services
Organizar/reutilizar código
Inicialização por demanda
Singleton
Exemplo: serviço usuários
User service
Profile Control.
Dashboard Control.
Profile View
Dashboard View
Angular - Services
angular.module('app', ['ionic']).
controller('MyController', ['$scope','notify',
function ($scope, notify) {
$scope.callNotify = function(msg) {
notify(msg);
};
}
]).
factory('notify', ['$window', function(win) {
var msgs = [];
return function(msg) {
msgs.push(msg);
if (msgs.length == 3) {
win.alert(msgs.join("\n"));
msgs = [];
}
};
}]);
<body ng-app="app">
<div id="simple" ng-controller="MyController">
<p>Serviço de notificação</p>
<input ng-init="message='test'" ng-model="message" >
<button ng-click="callNotify(message);">Notificar</button>
<p>(você precisa clicar 3 vezes para ver o alerta)</p>
</div>
</body>
JS
HTML
Angular - Scopes
Objeto referente ao model
A cola entre view e controller
Notifica diretivas
$rootScope e hierarquia
$rootScope
MainCtrl
UsersCtrl
ng-repeat
Angular - Scopes
angular.module('app', [])
.controller('GreetController', ['$scope', '$rootScope',
function($scope, $rootScope) {
$scope.name = 'World';
$rootScope.department = 'Angular';
}])
.controller('ListController', ['$scope', function($scope) {
$scope.names = ['Igor', 'Misko', 'Vojta'];
}]);
<body ng-app="app">
<div class="show-scope-demo">
<div ng-controller="GreetController">
Hello {{name}}!
</div>
<div ng-controller="ListController">
<ol>
<li ng-repeat="name in names">
{{name}} from {{department}}
</li>
</ol>
</div>
</div>
</body>
JS
HTML
Angular - Dependency Injection
Criar componentes
Resolver suas dependências
Fornecê-lo a outros componentes
Evitar dependências manuais (new)
A dependência é simplesmente entregue ao componente

someModule.controller('MyController', ['$scope', 'greeter',
function($scope, greeter) {
// ...
}
]);
Angular - Dependency Injection
var MyController = function($scope, greeter) {
// ...
}
MyController.$inject = ['$scope', 'greeter'];
someModule.controller('MyController', MyController);
someModule.controller('MyController', function($scope, greeter) {
// ...
});
Array de anotações em linha
Anotação com a propriedade $inject
Anotação implícita
Angular - Templates
HTML + elementos, atributos Angular
Template + ctrl + model = view
Arquivo único (index.html)
Um arquivo para cada view: fragmento ou página

Angular - AngularUI Router
Roteamento customizado
Rotas baseadas por estado
Um pouco além de links

Angular - AngularUI Router
angular.module('app', [])
.config(function($stateProvider, $urlRouterProvider, USER_ROLES){
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "app/templates/menu.html",
controller: 'MenuController'
})
.state('app.home', {
url: '/home',
views: {
'mainView':{
templateUrl: 'app/templates/home.html',
controller: 'MainController'
}
};
$urlRouterProvider.otherwise('/app/home');
})
Angular - Expressions
Código resolvido como valor
Geralmente utilizada para binding
Características
{{ 1+2 }}
{{ a+b }}
{{ user.name }}
{{ items[index] }}
Angular - Expressions
angular.module('app', []).
controller('EventController', ['$scope', function($scope) {
var counter = 0;
var names = ['Igor', 'Misko', 'Chirayu', 'Lucas'];
$scope.clickMe = function(clickEvent) {
$scope.name = names[counter % names.length];
counter++;
};
}]);
<body ng-app="app">
<div ng-controller="EventController">
<button ng-click="clickMe($event)">Clique</button>
<p id="one-time">Binding único: {{::name}}</p>
<p id="normal">Binding normal: {{name}}</p>
<p id="filter">Binding com filtro: {{12 | currency}}</p>
<p id="forgeting">Erro de referência?: {{name.ref}}</p>
</div>
</body>
JS
HTML
Angular - Filters
Formatação do valor da expression
Faça seu próprio filtro

Angular - Filters
angular.module('app', []).
controller('FilterController', function() {
this.array = [
{name: 'Jeff'},
{name: 'Igor'},
{name: 'James'},
{name: 'Brad'}
];
});
<body ng-app="app">
<div ng-controller="FilterController as ctrl">
Todos:
<span ng-repeat="entry in ctrl.array">{{entry.name}} <br/></span>
<br/>
Digite sua pesquisa:
<input ng-model="search"><br/>
<span ng-repeat="entry in ctrl.array | filter:search">
{{entry.name}}</br>
</span>
</div>
</body>
JS
HTML
Angular - Custom Filter
angular.module('app', [])
.filter('reverse', function() {
return function(input, uppercase) {
input = input || '';
var out = "";
for (var i = 0; i < input.length; i++) {
out = input.charAt(i) + out;
}
if (uppercase) {
out = out.toUpperCase();
}
return out;
};
})
.controller('MyController', ['$scope', function($scope) {
$scope.greeting = 'hello';
}]);
<body ng-app="app">
<div ng-controller="MyController">
<input ng-model="greeting" type="text"><br>
Invertido: {{greeting|reverse}}<br>
Invertido + uppercase: {{greeting|reverse:true}}<br>
</div>
</body>
JS
HTML
Angular - Forms
Entrada de dados
Serviços de validação
Melhor UX
Customização

Angular - Forms
angular.module('formExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.master = {};
$scope.update = function(user) {
$scope.master = angular.copy(user);
};
}]);
<style type="text/css">
.css-form input.ng-invalid.ng-touched {
background-color: #FA787E;
}
.css-form input.ng-valid.ng-touched {
background-color: #78FA89;
}
</style>
<body ng-app="app">
<div ng-controller="ExampleController">
<form novalidate class="css-form">
Nome: <input type="text" ng-model="user.name" required /><br />
E-mail: <input type="email" ng-model="user.email" required /><br />
Sexo: <input type="radio" ng-model="user.gender" value="male" />male
<input type="radio" ng-model="user.gender" value="female" />female<br />
<input type="submit" ng-click="update(user)" value="Save" />
</form>
</div>
</body>
JS
HTML
Angular - Directives
Atributos e elementos HTML
Comportamento customizado
Criar diretiva
Atenção com a nomenclatura
ngBind
ng-bind="name"
ng:bind="name"
ng_bind="name"
data-ng-bind="name"
x-ng-bind="name"
Templates, manipulação do DOM, event listeners, parâmetros
Angular - Directives
angular.module('app', [])
.controller('Controller', ['$scope', function($scope) {
$scope.customer = {
name: 'Naomi',
address: '1600 Amphitheatre'
};
}])
.directive('ddtCustomer', function() {
return {
template: function(elem, attr){
return '<span style="color:'+attr.color+';">Name: {{customer.name}}</span>'
}
};
});
<body ng-app="app">
<div ng-controller="Controller">
<div ddt-customer></div>
<ddt-customer color="red"/>
</div>
</body>
JS
HTML
Angular - Modules
Módulo global, inicialização
Separação de componentes
Reaproveitamento de código
Carga sem ordem, paralela

Angular - Modules
angular.module('app', ['app.login'])
.controller('LoginController', ['$scope', 'loginService',
function($scope, loginService) {
$scope.userdata = {
username: '',
password: ''
};
$scope.login = function(){
loginService.authenticate($scope.userdata);
}
}])
angular.module('app.login', [])
.factory('loginService', [function(){
loginService = {
authenticate : function(userdata){
// fazer login
return;
}
}
return loginService;
}])
JS
Desenvolvimento híbrido
O que é?
Write once, run anywhere
Aplicação nativa desenvolvida em outra tecnologia

Híbrido - Prós
Várias plataformas
Tamanhos de tela
+ barato, - tempo, - conhecimento
Ambiente e ferramentas
Fácil manutenção

Híbrido - Contras
Perda do potencial nativo
Desempenho
Interface específica

Apache Cordova
APIs JS para acesso ao dispositivo
Desenvolvimento HTML, CSS e JS
APIs multiplataforma
Empacotamento plataforma nativa

iOS, Android, Blackberry, Windows Phone, Palm WebOS, Bada, and Symbian
Apache Cordova
10/2012 Apache Software Foundation
Apache License 2.0
PhoneGap - Nitobi
WebView, APIs e plugins

Apache Cordova
WebView
APIs
Plugins
HTML5/CSS/JavaScript
Cordova Javascript API
Biblioteca nativa Cordova
API nativa da plataforma
Cordova - Plugin
App
Cordova Javascript API
Bridge interface
Plugin
Bridge Implementation
iOS
Android
...
usa
implementa
usa
Cordova - Instalação
$ sudo npm install -g cordova
C:\>npm install -g cordova
Linux
Windows
Pré-requisito: NodeJS (npm)
Cordova - CLI
$ cordova create hello com.example.hello HelloWorld
$ cd hello
# Mac
$ cordova platform add ios
$ cordova platform add amazon-fireos
$ cordova platform add android
$ cordova platform add blackberry10
$ cordova platform add firefoxos
# Windows
$ cordova platform add wp8
$ cordova platform add windows
$ cordova platform add amazon-fireos
$ cordova platform add android
$ cordova platform add blackberry10
$ cordova platform add firefoxos
Criando o app
Adicionar plataformas
Cordova - CLI
# Todas plataformas
$ cordova build
# Plataforma específica
$ cordova build android
$ cordova emulate android
Construindo o app
Emulando o app
$ cordova run android
Emulando diretamente no dispositivo
Pré-requisito: SDK(s) da(s) plataforma(s)
Cordova - Usando plugin
$ cordova plugin add cordova-plugin-battery-status
// batterystatus
window.addEventListener("batterystatus", onBatteryStatus, false);
function onBatteryStatus(info) {
console.log("Level: " + info.level + " isPlugged: " + info.isPlugged);
};
// batterycritical
window.addEventListener("batterycritical", onBatteryCritical, false);
function onBatteryCritical(info) {
alert("Battery Level Critical " + info.level + "%\nRecharge Soon!");
};
// batterylow
window.addEventListener("batterylow", onBatteryLow, false);
function onBatteryLow(info) {
alert("Battery Level Low " + info.level + "%");
}
Adicionar plugin
Usando o plugin
Ionic framework



+
Componentes de interface
CLI customizada
+
+
Ionic - Características
Interface parecida com a nativa
Foco na UI e UX
Grátis e open source
Componentes otimizados

Ionic - Plataformas


Disponível
Previsto


Links úteis

Contatos
Henrique Rotava <henrique.rotava@gmail.com>
Mateus Nava <mateus@inocode.com.br>
Rodrigo Rosa <rodrigocrosa@gmail.com>
Mauricio Tognon <mauricio@inocode.com.br>
Dia de Treinamento <contato@diadetreinamento.com.br>

Muito obrigado!

mobile
By Henrique Rotava
mobile
- 1,298