Este documento presenta información sobre aplicaciones multiplataforma y tecnologías relacionadas. Se discuten conceptos como aplicaciones de página única, frameworks como AngularJS, herramientas como Ionic y características de AngularJS como directivas, filtros y servicios. El documento también incluye ejemplos de código para ilustrar estos conceptos.
2. Índice
Jueves
Viernes
- Apps híbridas
- Diferencia entre nativas e híbridas
- Cómo funciona
- Ventajas e inconvenientes
- Ejemplos
- Historia
- Programar - prueba de los conceptos
- Otras herramientas y tecnologías
- Single Page Applications
- Frameworks
- Herramientas de trabajo
- AngularJS
- Ionic Framework
- Repaso general
3. Single Page Applications
Modelo tradicional
http://adrianalonso.es/2015/02/single-page-app-vs-multi-page-app/
El modelo SPA
La navegación entre páginas genera una petición
al servidor que devuelve el nuevo html a mostrar
por el navegador.
El cliente solicita páginas, y el servidor las crea y
las devuelve en cada petición.
Sólo se utiliza una página html en todo el proceso,
solicitando al servidor únicamente los datos que se
mostrarán en esta página.
El cliente solicita la página una vez y al navegar
realiza peticiones al servidor únicamente de los
datos, siendo el cliente (navegador) el que
construye el resultado final.
4. Ventajas
- La navegación y el renderizado se realiza en el cliente
—> Liberación de carga en servidor.
- Se evita solicitar o recargar elementos que no cambian en la navegación (headers, footers, etc.)
—> Renderizado de interfaz de usuario más rápido.
- Las llamadas al servidor se hacen sólo de los datos que se necesitan.
—> A través de servicios web y peticiones asíncronas.
- El cacheo y almacenamiento de datos temporales se realiza en el cliente.
—> Liberación de mantener sesiones en servidor.
- División total del front-end y el back-end.
—> El front-end podemos usarlo tanto para web como en app híbrida
- Parte de la lógica de programación pasa del servidor al cliente.
—> Liberación de procesamiento en servidor.
Single Page Applications
5. Inconvenientes
- Carga inicial puede ser mayor
—> Necesidad de obtener todos los elementos de la interfaz para mostrarlos posteriormente.
- Totalmente basado en Javascript. Si no está habilitado en el navegador, no funcionará.
—> Para Apps híbridas esto no afecta.
- Parte de la lógica de programación pasa del servidor al cliente.
—> Hay que tener cuidado de no pasar partes críticas de seguridad.
Single Page Applications
10. Frameworks
¿Por qué elegir sólo uno?
+
MVW Framework
Model
View
Whatever
Arquitectura
=
Maquetación y diseño
11. Herramientas de trabajo
npm gruntbower yeoman
Gestor de
paquetes
Gestor de
dependencias
Automatizador
de tareas
Generador de
proyectos
12. Herramientas de trabajo
¡Manos a la obra!
Instalar tecnologías necesarias
$ npm install -g grunt-cli bower yo generator-karma generator-angular
Crear y acceder a carpeta de la nueva app
$ mkdir demo && cd demo
Crear aplicación angular con yeoman
$ yo angular demo
13. Herramientas de trabajo
app/
WebApp generada con AngularJS como framework. Lo
veremos luego
bower_components/
Dependencias de la aplicación obtenidas con BOWER
node_modules/
Paquetes necesarios para la aplicación obtenidos con NPM
14. Herramientas de trabajo
bower.json
Archivo que contiene las dependencias de la aplicación
{
"name": "demo",
"version": "0.0.0",
"dependencies": {
"angular": "^1.3.0",
"angular-animate": "^1.3.0",
"angular-cookies": "^1.3.0",
"angular-resource": "^1.3.0",
"angular-route": "^1.3.0",
"angular-sanitize": "^1.3.0",
"angular-touch": "^1.3.0"
},
"devDependencies": {
"angular-mocks": "^1.3.0"
},
"appPath": "app",
"moduleName": "demoApp"
}
Se instalan mediante $ bower install
15. Herramientas de trabajo
package.json
Archivo que contiene los paquetes necesarios para el
proyecto
{
"name": "demo",
"version": "0.0.0",
"dependencies": {},
"repository": {},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-autoprefixer": "^2.0.0",
…
"load-grunt-tasks": "^3.1.0",
"time-grunt": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "grunt test"
}
}
Se instalan mediante $ npm install
16. Herramientas de trabajo
package.json
Archivo que contiene los paquetes necesarios para el
proyecto
{
"name": "demo",
"version": "0.0.0",
"dependencies": {},
"repository": {},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-autoprefixer": "^2.0.0",
…
"load-grunt-tasks": "^3.1.0",
"time-grunt": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "grunt test"
}
}
Se instalan mediante $ npm install
• version Coincidir versión exacta
• >version Debe ser mayor que la versión
• >=version Mayor o igual
• <version Menor
• <=version Menor o igual
• ~version Aproximadamente igual a la versión
• ^version Compatible con la versión
• 1.2.x Cualquier versión1.2.0, 1.2.1, etc., pero no 1.3.0
• http://... Versión de la URL ofrecida
• * Cualquier versión
• "" Cualquier versión también
• version1 - version2 Igual que >=version1 <=version2
• range1 || range2 Condicional
• git... Versión del repo git ofrecido
• user/repoVersión del repo GitHub ofrecido
• tag Una versión especifica tagged / etiquetada en git
• path/path/path Ruta local
19. AngularJS
Estructura
root / app module
module
config
routes
view controller
directives services
scope
…
Toda App es un módulo
20. AngularJS
Estructura
root / app module
module
config
routes
view controller
directives services
scope
A su vez una App puede dividirse en varios
módulos, y utilizar módulos externos o de
terceros
21. AngularJS
Estructura
root / app module
module
config
routes
view controller
directives services
scope
…
Cada módulo puede configurarse de forma
individual
22. AngularJS
Estructura
root / app module
module
config
routes
view controller
directives services
scope
…
La navegación en la App se gestiona a través
de rutas que enlazan vista y controlador
23. AngularJS
Estructura
root / app module
module
config
routes
view controller
directives services
scope
…
La vista es el
código HTML que
se muestra
24. AngularJS
Estructura
root / app module
module
config
routes
view controller
directives services
scope
…
En el controlador se encuentra
la lógica de la aplicación
25. AngularJS
Estructura
root / app module
module
config
routes
view controller
directives services
scope
…
El scope permite
la comunicación
entre vista y
controlador
26. AngularJS
Estructura
root / app module
module
config
routes
view controller
directives services
scope
…
Las directivas
permiten extender
el código HTML
27. AngularJS
Estructura
root / app module
module
config
routes
view controller
directives services
scope
…
Los servicios permiten
organizar y compartir código y
funcionalidades en distintas
partes de la aplicación
31. AngularJS
Controllers
angular.module(‘demoApp’).controller(‘MainCtrl’, [‘$scope’, function ($scope) {
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
// Código Javascript aquí. Lógica de presentación
$scope.miFunction = function() {
// También puede haber funciones invocadas desde la vista
}
$scope.on(‘destroy’, function() {
// Código que se ejecuta al destruirse el controlador
});
}]);
app/scripts/controllers/main.js
37. AngularJS
Data binding
¡Manos a la obra!
• Crear nuevo controlador y vista
• Añadirlos en el route de la app
• Compartir scope y valores entre controlador y vista
• Invocar funciones del controlador desde la vista
44. AngularJS
Services
app.factory(‘profile’, function() {
return {
“name”: “Anonymous”,
“login”: function() { … },
“logout”: function() { … }
}
}
app.service(‘profile’, function() {
this.name = “Anonymous”;
this.login = function() { … };
this.logout = function() { … };
}
app.controller(…., function($scope, registration) {
$scope.title = registration.title;
});
app.config(function($provide) {
$provide.provider(‘registration’, function() {
var type;
return {
setType: function(value) { type = value; },
$get: function() {
return {
title: ‘Service from Provider: ‘ + type
}
}
};
});
});
app.config(function(registrationProvider) {
registrationProvider.setType(‘Angular’);
});
Factory Service Provider
La forma más sencilla.
Devuelve una simple API con métodos
Parecido a factory pero devuelve una
clase completa
(objetos deben ser instanciados)
Es como un factory “configurable”. Es el tipo
más completo y a la vez complejo.
45. AngularJS
$http $http( {
method: ‘GET’,
url: ‘/unaURLCualquiera’,
params: objetoParams,
data: objetoOString,
headers: objetoHeaders,
cache: true,
timeout: 3000
})
.success(function(data, status, headers, config) {
// Ejecutar aquí el código cuando la petición se ha resuelto
})
.error(function(data, status, headers, config) {
// Ejecutar aquí el código cuando la petición ha fallado
});
46. AngularJS
$http $http( {
method: ‘GET’,
url: ‘/unaURLCualquiera’,
params: objetoParams,
data: objetoOString,
headers: objetoHeaders,
cache: true,
timeout: 3000
})
.success(function(data, status, headers, config) {
// Ejecutar aquí el código cuando la petición se ha resuelto
})
.error(function(data, status, headers, config) {
// Ejecutar aquí el código cuando la petición ha fallado
});
Métodos rápidos:
$http.get - $http.post - $http.put - $http.head - $http.delete - $http.json
Se puede sobreescribir la configuración por defecto mediante $httpProvider en la
configuración de la aplicación o módulo: $httpProvider.defaults.headers.XXXX = YYYY;
47. AngularJS
Directives, services, filters
¡Manos a la obra!
• Crear un servicio que devuelva un listado de datos (JSONArray)
• Utilizar ngRepeat para mostrar los resultados en la vista
• Filtrar los resultados con un filtro propio
• Sustituir el servicio por una petición a
http://jsonplaceholder.typicode.com/
49. Ionic Framework
Prototipar, maquetar y diseñar aplicaciones
web de forma sencilla y rápida
¡Manos a la obra!
Dos opciones:
- Nuevo proyecto:
$ yo ionic demo
- Proyecto existente:
$ bower install ionic —save
$ grunt wiredep
50. AngularJS
Buenas prácticas
• html5mode(true) —> URLs bonitas + SEO
• Directivas siempre como atributos —> soporte navegadores
• No modificar NUNCA el DOM en el controller —> hacerlo en la directiva (link)
• Evitar llamar a funciones del $scope en ng-repeat —> Demasiadas llamadas
• Utilizar ngIF en vez de ngShow cuando se pueda —> no modifica el DOM
• Usar one-time bindings (con ::) —> {{::miScopedVariable}}
• Utilizar siempre promesas —> Olvidarnos de los callbacks
• Utilizar $digest en vez de $apply —> $apply llama al digest desde el rootScope
• No utilizar funciones en los bindings —> son invocadas en cada digest