зеркало из https://github.com/DeGsoft/meanjs.git
reorginzed 0719 ok
This commit is contained in:
Родитель
119081e3d1
Коммит
6abf5a13f0
|
@ -1,49 +0,0 @@
|
|||
"use strict";
|
||||
var http = require('http'),
|
||||
url = require('url'),
|
||||
path = require('path'),
|
||||
fs = require('fs');
|
||||
|
||||
var mimeTypes = {
|
||||
"html": "text/html",
|
||||
"png": "image/png",
|
||||
"js": "text/javascript",
|
||||
"css": "text/css"
|
||||
};
|
||||
|
||||
http.createServer(staticServer).listen(3000);
|
||||
|
||||
function staticServer(req, res) {
|
||||
var pathname = url.parse(req.url).pathname;
|
||||
if (pathname === "/") {
|
||||
pathname = "index.html";
|
||||
}
|
||||
fileServer(res, pathname);
|
||||
}
|
||||
|
||||
function fileServer(res, pathname) {
|
||||
var filename = path.join(process.cwd(), pathname);
|
||||
var extension = path.extname(filename).split(".")[1];
|
||||
if (!extension) {
|
||||
extension = "html";
|
||||
filename += "." + extension;
|
||||
}
|
||||
fs.exists(filename, function (exists) {
|
||||
if (!exists) {
|
||||
notFound(res);
|
||||
} else {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': mimeTypes[extension]
|
||||
});
|
||||
fs.createReadStream(filename).pipe(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function notFound(res) {
|
||||
res.writeHead(404, {
|
||||
'Content-Type': 'text/html'
|
||||
});
|
||||
res.write("<html><head><meta charset='utf-8'></head><body><h1>404</h1> Nada por aquí</body></html>");
|
||||
res.end();
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
"use strict";
|
||||
var http = require('http'),
|
||||
url = require('url'),
|
||||
path = require('path'),
|
||||
fs = require('fs');
|
||||
|
||||
var mimeTypes = {
|
||||
"html": "text/html",
|
||||
"png": "image/png",
|
||||
"js": "text/javascript",
|
||||
"css": "text/css"
|
||||
};
|
||||
|
||||
http.createServer(staticServer).listen(3000);
|
||||
|
||||
function staticServer(req, res) {
|
||||
var pathname = url.parse(req.url).pathname;
|
||||
if (pathname === "/") {
|
||||
pathname = "index.html";
|
||||
}
|
||||
fileServer(res, pathname);
|
||||
}
|
||||
|
||||
function fileServer(res, pathname) {
|
||||
var filename = path.join(process.cwd(), pathname);
|
||||
var extension = path.extname(filename).split(".")[1];
|
||||
if (!extension) {
|
||||
extension = "html";
|
||||
filename += "." + extension;
|
||||
}
|
||||
fs.exists(filename, function (exists) {
|
||||
if (!exists) {
|
||||
notFound(res);
|
||||
} else {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': mimeTypes[extension]
|
||||
});
|
||||
fs.createReadStream(filename).pipe(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function notFound(res) {
|
||||
res.writeHead(404, {
|
||||
'Content-Type': 'text/html'
|
||||
});
|
||||
res.write("<html><head><meta charset='utf-8'></head><body><h1>404</h1> Nada por aquí</body></html>");
|
||||
res.end();
|
||||
}
|
|
@ -4,26 +4,26 @@ angular.module('cashFlow', ['ui.router']);
|
|||
// las rutas ahora se maneja con el concepto de estado
|
||||
angular.module('cashFlow').config(function ($stateProvider) {
|
||||
// Las rutas pasan a ser opcionales,
|
||||
// en la práctica sólo se usan si vienen de aplicaciones externas y por cuestiones de SEO
|
||||
$stateProvider
|
||||
.state('total', {
|
||||
url: '',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'total.html'
|
||||
})
|
||||
.state('nuevo', {
|
||||
// en la práctica sólo se usan si vienen de aplicaciones externas y por cuestiones de SEO
|
||||
$stateProvider
|
||||
.state('total', {
|
||||
url: '/',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'total.html'
|
||||
})
|
||||
.state('nuevo', {
|
||||
url: '/nuevo',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'nuevo.html'
|
||||
})
|
||||
.state('lista', {
|
||||
url: '/lista',
|
||||
templateUrl: 'nuevo.html'
|
||||
})
|
||||
.state('lista', {
|
||||
url: '/lista',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'lista.html'
|
||||
}).state('not-found', {
|
||||
url: '*path',
|
||||
templateUrl: 'not-found.html'
|
||||
});
|
||||
// realmente no existe un estado 'not found',
|
||||
// pero puede llegar rutas no controladas
|
||||
templateUrl: 'lista.html'
|
||||
}).state('not-found', {
|
||||
url: '*path',
|
||||
templateUrl: 'not-found.html'
|
||||
});
|
||||
// realmente no existe un estado 'not found',
|
||||
// pero puede llegar rutas no controladas
|
||||
});
|
||||
|
|
|
@ -1,40 +1,28 @@
|
|||
(function () {
|
||||
angular.module('cashFlow').controller('CajaCtrl', cajaCtrl);
|
||||
|
||||
var cajaCtrl = function (movimientosFactory) {
|
||||
var vm = this;
|
||||
function cajaCtrl(movimientosFactory, maestrosService) {
|
||||
var vm = this;
|
||||
|
||||
vm.titulo = "Controla tu Cash Flow";
|
||||
vm.maestros = {
|
||||
categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'],
|
||||
categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos']
|
||||
};
|
||||
vm.nuevoMovimiento = {
|
||||
esIngreso: 1,
|
||||
esGasto: 0,
|
||||
importe: 0,
|
||||
fecha: new Date()
|
||||
};
|
||||
vm.titulo = "Controla tu Cash Flow";
|
||||
vm.maestros = maestrosService.categorias;
|
||||
vm.nuevoMovimiento = {
|
||||
esIngreso: 1,
|
||||
esGasto: 0,
|
||||
importe: 0,
|
||||
fecha: new Date()
|
||||
};
|
||||
|
||||
vm.movimientos = movimientosFactory.getMovimientos();
|
||||
vm.total = movimientosFactory.getTotal();
|
||||
vm.movimientos = movimientosFactory.getMovimientos();
|
||||
vm.total = movimientosFactory.getTotal();
|
||||
|
||||
vm.guardarMovimiento = function () {
|
||||
var auxCopyMov = angular.copy(vm.nuevoMovimiento);
|
||||
movimientosFactory.postMovimiento(auxCopyMov);
|
||||
vm.nuevoMovimiento.importe = 0;
|
||||
}
|
||||
vm.balance = movimientosFactory.balance;
|
||||
vm.tipo = movimientosFactory.tipo;
|
||||
}
|
||||
|
||||
vm.guardarMovimiento = function () {
|
||||
if(vm.nuevoMovimiento.esIngreso){
|
||||
vm.total.ingresos += vm.nuevoMovimiento.importe;
|
||||
}else{
|
||||
vm.total.gastos += vm.nuevoMovimiento.importe;
|
||||
}
|
||||
var auxCopyMov = angular.copy(vm.nuevoMovimiento);
|
||||
auxCopyMov.tipo = vm.tipo(auxCopyMov);
|
||||
vm.movimientos.push(auxCopyMov);
|
||||
vm.nuevoMovimiento.importe = 0;
|
||||
}
|
||||
vm.balance = function () {
|
||||
return vm.total.ingresos - vm.total.gastos
|
||||
}
|
||||
vm.tipo = function (movimiento) {
|
||||
return movimiento.esIngreso && 'Ingreso' || 'Gasto'
|
||||
}
|
||||
}
|
||||
angular.module('cashFlow').controller('CajaCtrl', cajaCtrl);
|
||||
}());
|
||||
|
|
|
@ -1,50 +1,54 @@
|
|||
<html lang="es" ng-app="cashFlow">
|
||||
|
||||
<head>
|
||||
<title>Control de Caja</title>
|
||||
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<meta charset="utf-8" />
|
||||
<meta lang="es" />
|
||||
<meta name="description" content="Ejemplo Control de Caja en AngularJS por Alberto Basalo" />
|
||||
<meta name="author" content="Alberto Basalo @ Ágora Binaria" />
|
||||
<meta name="application-name" content="ControlAngularJS" />
|
||||
<meta name="Keywords" content="AngularJS, ejemplo, tutorial, curso" />
|
||||
<link rel="author" href="https://plus.google.com/+AlbertoBasalo71" />
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<title>Control de Caja</title>
|
||||
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<meta charset="utf-8" />
|
||||
<meta lang="es" />
|
||||
<meta name="description" content="Ejemplo Control de Caja en AngularJS por Alberto Basalo" />
|
||||
<meta name="author" content="Alberto Basalo @ Ágora Binaria" />
|
||||
<meta name="application-name" content="ControlAngularJS" />
|
||||
<meta name="Keywords" content="AngularJS, ejemplo, tutorial, curso" />
|
||||
<link rel="author" href="https://plus.google.com/+AlbertoBasalo71" />
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-default navbar-fixed-top" role="navigation" ng-controller="MenuCtrl as menu">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<ul class="nav navbar-nav">
|
||||
<nav class="navbar navbar-default navbar-fixed-top" role="navigation" ng-controller="MenuCtrl as menu">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<ul class="nav navbar-nav">
|
||||
<li ng-class="{ active: menu.isActive('total') }">
|
||||
<!-- Los enlaces se formulan como estado, con ui-sref -->
|
||||
<!-- Estos estados generan rutas, según la configuración -->
|
||||
<!-- Pero internamente siempre trabajamos con estados -->
|
||||
<a ui-sref="total">Totales</a>
|
||||
</li>
|
||||
<li ng-class="{ active: menu.isActive('nuevo') }">
|
||||
<a ui-sref="nuevo">Nuevo</a>
|
||||
</li>
|
||||
<li ng-class="{ active: menu.isActive('lista') }">
|
||||
<a ui-sref="lista">Lista</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- Los enlaces se formulan como estado, con ui-sref -->
|
||||
<!-- Estos estados generan rutas, según la configuración -->
|
||||
<!-- Pero internamente siempre trabajamos con estados -->
|
||||
<a ui-sref="total">Totales</a>
|
||||
</li>
|
||||
<li ng-class="{ active: menu.isActive('nuevo') }">
|
||||
<a ui-sref="nuevo">Nuevo</a>
|
||||
</li>
|
||||
<li ng-class="{ active: menu.isActive('lista') }">
|
||||
<a ui-sref="lista">Lista</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- La directiva de ui-router es... ui-view-->
|
||||
<div class="container text-center" style="padding-top:50px;" ui-view >
|
||||
<!-- En este caso podríamos tener varias vista a la vez-->
|
||||
<!-- Incluso estados anidados unos dentro de otros-->
|
||||
</div>
|
||||
<!-- JavaScript References -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
|
||||
<div class="container text-center" style="padding-top:50px;" ui-view>
|
||||
<!-- En este caso podríamos tener varias vista a la vez-->
|
||||
<!-- Incluso estados anidados unos dentro de otros-->
|
||||
</div>
|
||||
<!-- JavaScript References -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
|
||||
<!-- En lugar del enrutador de AngularJS, usaremos uno de terceros, llamado ui-router-->
|
||||
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
|
||||
<script src="app.js"></script>
|
||||
<script src="menuCtrl.js"></script>
|
||||
<script src="cajaCtrl.js"></script>
|
||||
<script src="movimientosFactory.js"></script>
|
||||
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
|
||||
<script src="app.js"></script>
|
||||
<script src="menuCtrl.js"></script>
|
||||
<script src="cajaCtrl.js"></script>
|
||||
<script src="maestrosService.js"></script>
|
||||
<script src="movimientosFactory.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
(function () {
|
||||
|
||||
angular.module('cashFlow').service('maestrosService', maestrosService);
|
||||
|
||||
function maestrosService() {
|
||||
this.categorias = {
|
||||
categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'],
|
||||
categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos']
|
||||
};
|
||||
}
|
||||
|
||||
}());
|
|
@ -1,10 +1,10 @@
|
|||
(function () {
|
||||
angular.module('cashFlow').controller('MenuCtrl', menuCtrl);
|
||||
// Ahora el sercvicio se llama $state
|
||||
var menuCtrl = function ($state) {
|
||||
function menuCtrl($state) {
|
||||
this.isActive = function (estado) {
|
||||
// Tiene funciones más amigables para consultar
|
||||
return $state.is(estado);
|
||||
}
|
||||
}
|
||||
angular.module('cashFlow').controller('MenuCtrl', menuCtrl);
|
||||
}());
|
||||
|
|
|
@ -1,26 +1,43 @@
|
|||
(function () {
|
||||
var movimientosFactory = function () {
|
||||
|
||||
angular.module('cashFlow').factory('movimientosFactory', movimientosFactory);
|
||||
|
||||
function movimientosFactory() {
|
||||
|
||||
var movimientos = [];
|
||||
|
||||
var total = {
|
||||
ingresos: 0,
|
||||
gastos: 0
|
||||
};
|
||||
|
||||
var result = {};
|
||||
|
||||
var factory = {};
|
||||
factory.getMovimientos = function () {
|
||||
|
||||
result.getMovimientos = function () {
|
||||
return movimientos;
|
||||
};
|
||||
factory.getTotal = function () {
|
||||
|
||||
result.getTotal = function () {
|
||||
return total;
|
||||
};
|
||||
factory.postMovimiento = function (movimiento) {
|
||||
|
||||
result.postMovimiento = function (movimiento) {
|
||||
movimientos.push(movimiento);
|
||||
total.ingresos += movimiento.esIngreso * movimiento.importe;
|
||||
total.gastos += movimiento.esGasto * movimiento.importe;
|
||||
};
|
||||
return factory;
|
||||
|
||||
result.balance = function () {
|
||||
return total.ingresos - total.gastos
|
||||
}
|
||||
|
||||
result.tipo = function (movimiento) {
|
||||
return movimiento.esIngreso && 'Ingreso' || 'Gasto'
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
angular.module('cashFlow').factory('movimientosFactory', movimientosFactory);
|
||||
}());
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
"use strict";
|
||||
var http = require('http'),
|
||||
url = require('url'),
|
||||
path = require('path'),
|
||||
fs = require('fs');
|
||||
|
||||
var mimeTypes = {
|
||||
"html": "text/html",
|
||||
"png": "image/png",
|
||||
"js": "text/javascript",
|
||||
"css": "text/css"
|
||||
};
|
||||
|
||||
http.createServer(staticServer).listen(3000);
|
||||
|
||||
function staticServer(req, res) {
|
||||
var pathname = url.parse(req.url).pathname;
|
||||
if (pathname === "/") {
|
||||
pathname = "index.html";
|
||||
}
|
||||
fileServer(res, pathname);
|
||||
}
|
||||
|
||||
function fileServer(res, pathname) {
|
||||
var filename = path.join(process.cwd(), pathname);
|
||||
var extension = path.extname(filename).split(".")[1];
|
||||
if (!extension) {
|
||||
extension = "html";
|
||||
filename += "." + extension;
|
||||
}
|
||||
fs.exists(filename, function (exists) {
|
||||
if (!exists) {
|
||||
notFound(res);
|
||||
} else {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': mimeTypes[extension]
|
||||
});
|
||||
fs.createReadStream(filename).pipe(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function notFound(res) {
|
||||
res.writeHead(404, {
|
||||
'Content-Type': 'text/html'
|
||||
});
|
||||
res.write("<html><head><meta charset='utf-8'></head><body><h1>404</h1> Nada por aquí</body></html>");
|
||||
res.end();
|
||||
}
|
|
@ -1,38 +1,35 @@
|
|||
<!-- Cada sección tendrá su propia plantilla -->
|
||||
<!-- No se especifíca el controlador, que será asignado por el enrutador -->
|
||||
<section name="total">
|
||||
<!-- Pero se supone un viweModel llamado caja-->
|
||||
<h1>{{ caja.titulo }}</h1>
|
||||
<p class="lead">Comprueba de dónde viene y a dónde va tu dinero.</p>
|
||||
<div class="row-fluid">
|
||||
<div class="row placeholders">
|
||||
<div class="col-xs-8 col-sm-4 placeholder">
|
||||
<h1>
|
||||
<h1>{{ caja.titulo }}</h1>
|
||||
<p class="lead">Comprueba de dónde viene y a dónde va tu dinero.</p>
|
||||
<div class="row-fluid">
|
||||
<div class="row placeholders">
|
||||
<div class="col-xs-8 col-sm-4 placeholder">
|
||||
<h1>
|
||||
<span class="label label-success">
|
||||
{{ caja.total.ingresos | number:2 }} €
|
||||
</span>
|
||||
</h1>
|
||||
<h4>Total ingresos</h4>
|
||||
<span class="text-muted">Acumulado</span>
|
||||
</div>
|
||||
<div class="col-xs-8 col-sm-4 placeholder">
|
||||
<h1>
|
||||
<h4>Total ingresos</h4>
|
||||
<span class="text-muted">Acumulado</span>
|
||||
</div>
|
||||
<div class="col-xs-8 col-sm-4 placeholder">
|
||||
<h1>
|
||||
<span class="label label-danger">
|
||||
{{ caja.total.gastos | number:2 }} €
|
||||
</span>
|
||||
</h1>
|
||||
<h4>Total gastos</h4>
|
||||
<span class="text-muted">Acumulado</span>
|
||||
</div>
|
||||
<div class="col-xs-8 col-sm-4 placeholder">
|
||||
<h1>
|
||||
<h4>Total gastos</h4>
|
||||
<span class="text-muted">Acumulado</span>
|
||||
</div>
|
||||
<div class="col-xs-8 col-sm-4 placeholder">
|
||||
<h1>
|
||||
<span class="label " ng-class="{'label-success': caja.balance()>=0 , 'label-danger' : caja.balance()<0}">
|
||||
{{ caja.balance() | number:2 }} €
|
||||
</span>
|
||||
</h1>
|
||||
<h4>Balance</h4>
|
||||
<span class="text-muted">Ingresos-Gastos</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h4>Balance</h4>
|
||||
<span class="text-muted">Ingresos-Gastos</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// tenemos que agregar la dependencia hacia el nuevo módulo de filtros
|
||||
angular.module('cashFlow', ['ui.router', 'abFiltros']);
|
||||
|
||||
angular.module('cashFlow').config(function ($stateProvider) {
|
||||
$stateProvider
|
||||
.state('total', {
|
||||
url: '/',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'total.html'
|
||||
})
|
||||
.state('nuevo', {
|
||||
url: '/nuevo',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'nuevo.html'
|
||||
})
|
||||
.state('lista', {
|
||||
url: '/lista',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'lista.html'
|
||||
}).state('not-found', {
|
||||
url: '*path',
|
||||
templateUrl: 'not-found.html'
|
||||
});
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
(function () {
|
||||
var cajaCtrl = function (movimientosFactory, maestrosService) {
|
||||
var vm = this;
|
||||
|
||||
vm.titulo = "Controla tu Cash Flow";
|
||||
vm.maestros = maestrosService.categorias;
|
||||
vm.nuevoMovimiento = {
|
||||
esIngreso: 1,
|
||||
esGasto: 0,
|
||||
importe: 0,
|
||||
fecha: new Date()
|
||||
};
|
||||
vm.movimientos = movimientosFactory.getMovimientos();
|
||||
vm.total = movimientosFactory.getTotal();
|
||||
|
||||
vm.guardarMovimiento = function () {
|
||||
var auxCopyMov = angular.copy(vm.nuevoMovimiento);
|
||||
movimientosFactory.postMovimiento(auxCopyMov);
|
||||
vm.nuevoMovimiento.importe = 0;
|
||||
}
|
||||
vm.balance = movimientosFactory.balance;
|
||||
vm.tipo = movimientosFactory.tipo;
|
||||
}
|
||||
angular.module('cashFlow').controller('CajaCtrl', cajaCtrl);
|
||||
}());
|
|
@ -1,6 +1,16 @@
|
|||
(function () {
|
||||
|
||||
// Podemos usar una sintaxis fluida y declarar todo en una solo línea
|
||||
// Atención a la declaración de un nuevo módulo genérico
|
||||
angular.module('abFiltros', [])
|
||||
.filter('abLimpiarCadena', limpiarCadena)
|
||||
.filter('abRecortar', recortar)
|
||||
.filter('abRellenarVacios', rellenarVacios)
|
||||
.filter('abGranImporte', granImporte);
|
||||
|
||||
// Los filtros se declaran como funciones que a su vez devuelven... funciones
|
||||
|
||||
|
||||
// Esas funciones internas se aplican sobre los valores,
|
||||
// Tienen al menos un parámetro, que sirve de entrada
|
||||
|
||||
|
@ -73,12 +83,4 @@
|
|||
};
|
||||
return funcionFiltro;
|
||||
}
|
||||
|
||||
// Podemos usar una sintaxis fluida y declarar todo en una solo línea
|
||||
// Atención a la declaración de un nuevo módulo genérico
|
||||
angular.module('abFiltros', [])
|
||||
.filter('abLimpiarCadena', limpiarCadena)
|
||||
.filter('abRecortar', recortar)
|
||||
.filter('abRellenarVacios', rellenarVacios)
|
||||
.filter('abGranImporte', granImporte);
|
||||
}());
|
|
@ -0,0 +1,51 @@
|
|||
<html lang="es" ng-app="cashFlow">
|
||||
|
||||
<head>
|
||||
<title>Control de Caja</title>
|
||||
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<meta charset="utf-8" />
|
||||
<meta lang="es" />
|
||||
<meta name="description" content="Ejemplo Control de Caja en AngularJS por Alberto Basalo" />
|
||||
<meta name="author" content="Alberto Basalo @ Ágora Binaria" />
|
||||
<meta name="application-name" content="ControlAngularJS" />
|
||||
<meta name="Keywords" content="AngularJS, ejemplo, tutorial, curso" />
|
||||
<link rel="author" href="https://plus.google.com/+AlbertoBasalo71" />
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-default navbar-fixed-top" role="navigation" ng-controller="MenuCtrl as menu">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<ul class="nav navbar-nav">
|
||||
<li ng-class="{ active: menu.isActive('total') }">
|
||||
<a ui-sref="total">Totales</a>
|
||||
</li>
|
||||
<li ng-class="{ active: menu.isActive('nuevo') }">
|
||||
<a ui-sref="nuevo">Nuevo</a>
|
||||
</li>
|
||||
<li ng-class="{ active: menu.isActive('lista') }">
|
||||
<a ui-sref="lista">Lista</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container text-center" style="padding-top:50px;" ui-view>
|
||||
|
||||
</div>
|
||||
<!-- JavaScript References -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
|
||||
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
|
||||
<script src="app.js"></script>
|
||||
<script src="menuCtrl.js"></script>
|
||||
<script src="cajaCtrl.js"></script>
|
||||
<script src="maestrosService.js"></script>
|
||||
<script src="movimientosFactory.js"></script>
|
||||
<!-- Incluir el fichero dónde se han programado los filtros-->
|
||||
<script src="filtros.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,29 @@
|
|||
<section name="Lista">
|
||||
<p class="lead">Estos son tus movimientos recientes.</p>
|
||||
<br>
|
||||
<label class="control-label" for="importe">Filtrar:</label>
|
||||
<input type="text" name="filtro" placeholder="qué buscas?" class="input" ng-model="caja.valorBuscado">
|
||||
<button class="btn-primary" ng-click="caja.valorCorte=0">Ver todos los movimientos</button>
|
||||
<button class="btn-danger" ng-click="caja.valorCorte=1000">Sólo grandes movimientos</button>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><a href="" ng-click="caja.campo = 'fecha'; caja.sentido = !caja.sentido ">Fecha</a>
|
||||
</th>
|
||||
<th>Tipo</th>
|
||||
<th>Categoría</th>
|
||||
<th><a href="" ng-click="caja.campo = 'importe'; caja.sentido = !caja.sentido ">Importe</a>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Usamos el filtro Gran Importe sobre un array -->
|
||||
<tr ng-repeat="movimiento in caja.movimientos | abGranImporte:caja.valorCorte | filter:caja.valorBuscado | orderBy:caja.campo:caja.sentido">
|
||||
<td class="text-left">{{movimiento.fecha | date}}</td>
|
||||
<td class="text-left">{{movimiento.tipo}}</td>
|
||||
<td class="text-left">{{movimiento.categoria}}</td>
|
||||
<td class="text-left" ng-class="{'text-success': movimiento.tipo=='Ingreso', 'text-danger' : movimiento.tipo=='Gasto'}">{{movimiento.importe | number:2}} €</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
|
@ -0,0 +1,10 @@
|
|||
(function () {
|
||||
angular.module('cashFlow').service('maestrosService', maestrosService);
|
||||
|
||||
function maestrosService() {
|
||||
this.categorias = {
|
||||
categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'],
|
||||
categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos']
|
||||
};
|
||||
}
|
||||
}());
|
|
@ -0,0 +1,10 @@
|
|||
(function () {
|
||||
angular.module('cashFlow').controller('MenuCtrl', menuCtrl);
|
||||
|
||||
function menuCtrl($state) {
|
||||
this.isActive = function (estado) {
|
||||
return $state.is(estado);
|
||||
}
|
||||
}
|
||||
|
||||
}());
|
|
@ -0,0 +1,38 @@
|
|||
(function () {
|
||||
angular.module('cashFlow').factory('movimientosFactory', movimientosFactory);
|
||||
|
||||
function movimientosFactory() {
|
||||
|
||||
var movimientos = [];
|
||||
var total = {
|
||||
ingresos: 0,
|
||||
gastos: 0
|
||||
};
|
||||
var result = {};
|
||||
|
||||
result.getMovimientos = function () {
|
||||
return movimientos;
|
||||
};
|
||||
|
||||
result.getTotal = function () {
|
||||
return total;
|
||||
};
|
||||
|
||||
result.postMovimiento = function (movimiento) {
|
||||
movimientos.push(movimiento);
|
||||
total.ingresos += movimiento.esIngreso * movimiento.importe;
|
||||
total.gastos += movimiento.esGasto * movimiento.importe;
|
||||
};
|
||||
|
||||
result.balance = function () {
|
||||
return total.ingresos - total.gastos
|
||||
}
|
||||
|
||||
result.tipo = function (movimiento) {
|
||||
return movimiento.esIngreso && 'Ingreso' || 'Gasto'
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
}());
|
|
@ -0,0 +1,52 @@
|
|||
<section name="nuevoMovimiento" class="row-fluid">
|
||||
<form class="form-horizontal text-left">
|
||||
<fieldset>
|
||||
<div id="legend">
|
||||
<legend class="">Introduce tus movimientos</legend>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="col-xs-12 col-sm-6">
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="tipo">Tipo</label>
|
||||
<div class="controls">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-success" ng-class="{'active':caja.nuevoMovimiento.esIngreso}" ng-click="caja.nuevoMovimiento.esIngreso=1; caja.nuevoMovimiento.esGasto=0">
|
||||
<span ng-class="{'small':caja.nuevoMovimiento.esGasto}">+ Ingreso</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-danger" ng-class="{'active':caja.nuevoMovimiento.esGasto}" ng-click="caja.nuevoMovimiento.esIngreso=0; caja.nuevoMovimiento.esGasto=1">
|
||||
<span ng-class="{'small':caja.nuevoMovimiento.esIngreso}">- Gasto</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="categ">Categoría</label>
|
||||
<div class="controls">
|
||||
<select ng-show="caja.nuevoMovimiento.esIngreso" name="categoria" ng-model="caja.nuevoMovimiento.categoria" ng-options="categoria for categoria in caja.maestros.categoriasIngresos"></select>
|
||||
<select ng-show="caja.nuevoMovimiento.esGasto" name="categoria" ng-model="caja.nuevoMovimiento.categoria" ng-options="categoria for categoria in caja.maestros.categoriasGastos"></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6">
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="fecha">Fecha</label>
|
||||
<div class="controls">
|
||||
<input type="date" name="fecha" placeholder="" class="input" ng-model="caja.nuevoMovimiento.fecha">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="importe">Importe</label>
|
||||
<div class="controls">
|
||||
<input type="number" name="importe" placeholder="" class="input" ng-model="caja.nuevoMovimiento.importe">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<button style="margin-top: 20px" type="button" class="btn btn-lg btn-primary" ng-click="caja.guardarMovimiento()">
|
||||
<span>Guardar {{ caja.tipo(caja.nuevoMovimiento) }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</section>
|
|
@ -1,8 +0,0 @@
|
|||
(function () {
|
||||
var menuCtrl = function ($state) {
|
||||
this.isActive = function (estado) {
|
||||
return $state.is(estado);
|
||||
}
|
||||
}
|
||||
angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl);
|
||||
}());
|
|
@ -1,26 +1,26 @@
|
|||
// tenemos que cambiar la dependencia hacia el nuevo módulo
|
||||
angular.module('controlCajaApp', ['ui.router']);
|
||||
|
||||
// las rutas ahora se maneja con el concepto de estado
|
||||
angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) {
|
||||
$stateProvider
|
||||
.state('total', {
|
||||
url: '/',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'total.html'
|
||||
})
|
||||
.state('nuevo', {
|
||||
url: '/nuevo',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'nuevo.html'
|
||||
})
|
||||
.state('lista', {
|
||||
url: '/lista',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'lista.html'
|
||||
}).state('not-found', {
|
||||
url: '*path',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'total.html'
|
||||
});
|
||||
});
|
||||
// tenemos que cambiar la dependencia hacia el nuevo módulo
|
||||
angular.module('controlCajaApp', ['ui.router']);
|
||||
|
||||
// las rutas ahora se maneja con el concepto de estado
|
||||
angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) {
|
||||
$stateProvider
|
||||
.state('total', {
|
||||
url: '/',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'total.html'
|
||||
})
|
||||
.state('nuevo', {
|
||||
url: '/nuevo',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'nuevo.html'
|
||||
})
|
||||
.state('lista', {
|
||||
url: '/lista',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'lista.html'
|
||||
}).state('not-found', {
|
||||
url: '*path',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'total.html'
|
||||
});
|
||||
});
|
|
@ -1,40 +1,40 @@
|
|||
(function () {
|
||||
// El controlador ahora tiene una dependencia de la factoría
|
||||
var cajaCtrl = function (movimientosFactory) {
|
||||
var vm = this;
|
||||
|
||||
vm.titulo = "Controla tu Cash Flow";
|
||||
vm.maestros = {
|
||||
categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'],
|
||||
categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos']
|
||||
};
|
||||
vm.nuevoMovimiento = {
|
||||
esIngreso: 1,
|
||||
esGasto: 0,
|
||||
importe: 0,
|
||||
fecha: new Date()
|
||||
};
|
||||
// La parte de datos que debe compartir la delega sobre la factoría
|
||||
vm.movimientos = movimientosFactory.getMovimientos();
|
||||
vm.total = movimientosFactory.getTotal();
|
||||
|
||||
vm.guardarMovimiento = function () {
|
||||
if(vm.nuevoMovimiento.esIngreso){
|
||||
vm.total.ingresos += vm.nuevoMovimiento.importe;
|
||||
}else{
|
||||
vm.total.gastos += vm.nuevoMovimiento.importe;
|
||||
}
|
||||
var auxCopyMov = angular.copy(vm.nuevoMovimiento);
|
||||
auxCopyMov.tipo = vm.tipo(auxCopyMov);
|
||||
vm.movimientos.push(auxCopyMov);
|
||||
vm.nuevoMovimiento.importe = 0;
|
||||
}
|
||||
vm.balance = function () {
|
||||
return vm.total.ingresos - vm.total.gastos
|
||||
}
|
||||
vm.tipo = function (movimiento) {
|
||||
return movimiento.esIngreso && 'Ingreso' || 'Gasto'
|
||||
}
|
||||
}
|
||||
angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl);
|
||||
}());
|
||||
(function () {
|
||||
// El controlador ahora tiene una dependencia de la factoría
|
||||
var cajaCtrl = function (movimientosFactory) {
|
||||
var vm = this;
|
||||
|
||||
vm.titulo = "Controla tu Cash Flow";
|
||||
vm.maestros = {
|
||||
categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'],
|
||||
categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos']
|
||||
};
|
||||
vm.nuevoMovimiento = {
|
||||
esIngreso: 1,
|
||||
esGasto: 0,
|
||||
importe: 0,
|
||||
fecha: new Date()
|
||||
};
|
||||
// La parte de datos que debe compartir la delega sobre la factoría
|
||||
vm.movimientos = movimientosFactory.getMovimientos();
|
||||
vm.total = movimientosFactory.getTotal();
|
||||
|
||||
vm.guardarMovimiento = function () {
|
||||
if(vm.nuevoMovimiento.esIngreso){
|
||||
vm.total.ingresos += vm.nuevoMovimiento.importe;
|
||||
}else{
|
||||
vm.total.gastos += vm.nuevoMovimiento.importe;
|
||||
}
|
||||
var auxCopyMov = angular.copy(vm.nuevoMovimiento);
|
||||
auxCopyMov.tipo = vm.tipo(auxCopyMov);
|
||||
vm.movimientos.push(auxCopyMov);
|
||||
vm.nuevoMovimiento.importe = 0;
|
||||
}
|
||||
vm.balance = function () {
|
||||
return vm.total.ingresos - vm.total.gastos
|
||||
}
|
||||
vm.tipo = function (movimiento) {
|
||||
return movimiento.esIngreso && 'Ingreso' || 'Gasto'
|
||||
}
|
||||
}
|
||||
angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl);
|
||||
}());
|
|
@ -1,48 +1,48 @@
|
|||
<html lang="es" ng-app="controlCajaApp">
|
||||
<head>
|
||||
<title>Control de Caja</title>
|
||||
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<meta charset="utf-8" />
|
||||
<meta lang="es" />
|
||||
<meta name="description" content="Ejemplo Control de Caja en AngularJS por Alberto Basalo" />
|
||||
<meta name="author" content="Alberto Basalo @ Ágora Binaria" />
|
||||
<meta name="application-name" content="ControlAngularJS" />
|
||||
<meta name="Keywords" content="AngularJS, ejemplo, tutorial, curso" />
|
||||
<link rel="author" href="https://plus.google.com/+AlbertoBasalo71" />
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-default navbar-fixed-top" role="navigation" ng-controller="MenuCtrl as menu">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<ul class="nav navbar-nav">
|
||||
<!-- Los enlaces se formulan como estado, con ui-sref-->
|
||||
<li ng-class="{ active: menu.isActive('total') }">
|
||||
<a ui-sref="total">Totales</a>
|
||||
</li>
|
||||
<li ng-class="{ active: menu.isActive('nuevo') }">
|
||||
<a ui-sref="nuevo">Nuevo</a>
|
||||
</li>
|
||||
<li ng-class="{ active: menu.isActive('lista') }">
|
||||
<a ui-sref="lista">Lista</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- La directiva de ui-router es... ui-view-->
|
||||
<div class="container text-center" style="padding-top:50px;" ui-view >
|
||||
|
||||
</div>
|
||||
<!-- JavaScript References -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
|
||||
<!-- En lugar del enrutador de angularJs, usaremos uno de terceros, llamado ui-router-->
|
||||
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
|
||||
<script src="app.js"></script>
|
||||
<script src="menuCtrl.js"></script>
|
||||
<script src="cajaCtrl.js"></script>
|
||||
<!-- Referencia a la factoría recién creada -->
|
||||
<script src="movimientosFactory.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
<html lang="es" ng-app="controlCajaApp">
|
||||
<head>
|
||||
<title>Control de Caja</title>
|
||||
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<meta charset="utf-8" />
|
||||
<meta lang="es" />
|
||||
<meta name="description" content="Ejemplo Control de Caja en AngularJS por Alberto Basalo" />
|
||||
<meta name="author" content="Alberto Basalo @ Ágora Binaria" />
|
||||
<meta name="application-name" content="ControlAngularJS" />
|
||||
<meta name="Keywords" content="AngularJS, ejemplo, tutorial, curso" />
|
||||
<link rel="author" href="https://plus.google.com/+AlbertoBasalo71" />
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-default navbar-fixed-top" role="navigation" ng-controller="MenuCtrl as menu">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<ul class="nav navbar-nav">
|
||||
<!-- Los enlaces se formulan como estado, con ui-sref-->
|
||||
<li ng-class="{ active: menu.isActive('total') }">
|
||||
<a ui-sref="total">Totales</a>
|
||||
</li>
|
||||
<li ng-class="{ active: menu.isActive('nuevo') }">
|
||||
<a ui-sref="nuevo">Nuevo</a>
|
||||
</li>
|
||||
<li ng-class="{ active: menu.isActive('lista') }">
|
||||
<a ui-sref="lista">Lista</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- La directiva de ui-router es... ui-view-->
|
||||
<div class="container text-center" style="padding-top:50px;" ui-view >
|
||||
|
||||
</div>
|
||||
<!-- JavaScript References -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
|
||||
<!-- En lugar del enrutador de angularJs, usaremos uno de terceros, llamado ui-router-->
|
||||
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
|
||||
<script src="app.js"></script>
|
||||
<script src="menuCtrl.js"></script>
|
||||
<script src="cajaCtrl.js"></script>
|
||||
<!-- Referencia a la factoría recién creada -->
|
||||
<script src="movimientosFactory.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,34 +1,34 @@
|
|||
(function () {
|
||||
// Las factorías, y los servicios, son funciones estándar
|
||||
// Una gran diferencia con los controladores es que son singleton
|
||||
// Eso los convierte en un buen lugar para compartir datos
|
||||
var movimientosFactory = function () {
|
||||
// el array de movimientos y el total lo mantiene la factoría
|
||||
// de esta forma sobrevive a las recargas de controladores
|
||||
var movimientos = [];
|
||||
var total = {
|
||||
ingresos: 0,
|
||||
gastos: 0
|
||||
};
|
||||
|
||||
|
||||
var factory = {};
|
||||
factory.getMovimientos = function () {
|
||||
return movimientos;
|
||||
};
|
||||
factory.getTotal = function () {
|
||||
return total;
|
||||
};
|
||||
factory.postMovimiento = function (movimiento) {
|
||||
movimientos.push(movimiento);
|
||||
total.ingresos += movimiento.esIngreso * movimiento.importe;
|
||||
total.gastos += movimiento.esGasto * movimiento.importe;
|
||||
};
|
||||
// las factorias siempre devuelven objetos
|
||||
// Estos objetos pueden contener funciones de lógica reutilizables
|
||||
return factory;
|
||||
};
|
||||
|
||||
angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory);
|
||||
}());
|
||||
|
||||
(function () {
|
||||
// Las factorías, y los servicios, son funciones estándar
|
||||
// Una gran diferencia con los controladores es que son singleton
|
||||
// Eso los convierte en un buen lugar para compartir datos
|
||||
var movimientosFactory = function () {
|
||||
// el array de movimientos y el total lo mantiene la factoría
|
||||
// de esta forma sobrevive a las recargas de controladores
|
||||
var movimientos = [];
|
||||
var total = {
|
||||
ingresos: 0,
|
||||
gastos: 0
|
||||
};
|
||||
|
||||
|
||||
var factory = {};
|
||||
factory.getMovimientos = function () {
|
||||
return movimientos;
|
||||
};
|
||||
factory.getTotal = function () {
|
||||
return total;
|
||||
};
|
||||
factory.postMovimiento = function (movimiento) {
|
||||
movimientos.push(movimiento);
|
||||
total.ingresos += movimiento.esIngreso * movimiento.importe;
|
||||
total.gastos += movimiento.esGasto * movimiento.importe;
|
||||
};
|
||||
// las factorias siempre devuelven objetos
|
||||
// Estos objetos pueden contener funciones de lógica reutilizables
|
||||
return factory;
|
||||
};
|
||||
|
||||
angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory);
|
||||
}());
|
||||
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче