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