Lorenzo Gonzalez Gascón
I'm teacher in computer Science in a high school, the high school is named "CIPFP Mislata" in Spain-Valencia-Mislata .
12 de Marzo de 2015
¿Quieres que mis alumnos hagan las prácticas en tu empresa?
¡Ponte en contacto conmigo!
Evita repetir código en los DAO
Realiza la coordinación entre DAOs
Enriquece el modelo
Unificar comportamiento entre DAOs
Solo realizan una única tarea:
HTTP,
HTML5 Storage,
etc.
NOTA:Obviamente en JavaScript no hay interfaces, pero es para que se entienda
Inicialmente no hace nada solo pasa datos pero sirve para
poder modificarla libremente
MiClase.$inject=['$http','$log']
function MiClase($http,$log) {
}
var miClase = $injector.instantiate(MiClase);
Definir dependencias en una clase
Crear una instancia
var locals = {
$log: miNuevoLog
};
var miClase = $injector.instantiate(MiClase,locals);
Sobreescribir inyecciones (realmente pasar parámetros)
var miFuncion=['$http','$log',function($http,$log) {
}]
$injector.invoke(miFuncion,elThis);
Función con inyección de dependencias
Ejecutar la función
var locals = {
$log: miNuevoLog
};
var resultado = $injector.invoke(miFuncion,elThis,locals);
Sobreescribir inyecciones (realmente pasar parámetros)
var urlExpression=$interpolate("/api/{{entityName}}/{{id}}");
var urlUsuario=urlExpression({
entityName:"Usuario",
id:3
});
var urlEmpresa=urlExpression({
entityName:"Empresa",
id:12
});
urlUsuario="/api/Usuario/3" urlEmpresa="/api/Empresa/12"
El resultado es:
La expresión se puede reusar
angular.module("name").service("usuarioRemoteDAO", UsuarioRemoteDAO);
angular.module("name").service("compraRemoteDAO", CompraRemoteDAO);
angular.module("name").service("movimientoRemoteDAO", MovimientoRemoteDAO);
angular.module("name").service("rolRemoteDAO", RolRemoteDAO);
angular.module("name").service("tarjetaRemoteDAO", TarjetaRemoteDAO);
angular.module("name").service("alumnoRemoteDAO", AlumnoRemoteDAO);
angular.module("name").service("usuarioRepository", UsuarioRepository);
angular.module("name").service("compraRepository", CompraRepository);
angular.module("name").service("movimientoRepository", MovimientoRepository);
angular.module("name").service("rolRepository", RolRepository);
angular.module("name").service("tarjetaRepository", TarjetaRepository);
angular.module("name").service("alumnoRepository", AlumnoRepository);
angular.module("name").service("usuarioService", UsuarioService);
angular.module("name").service("compraService", CompraService);
angular.module("name").service("movimientoService", MovimientoService);
angular.module("name").service("rolService", RolService);
angular.module("name").service("tarjetaService", TarjetaService);
angular.module("name").service("alumnoService", AlumnoService);
angular.module("name").service("serviceFactory", ServiceFactory);
angular.module("name").service("repositoryFactory", RepositoryFactory);
angular.module("name").service("remoteDAOFactory", RemoteDAOFactory);
Únicamente 3 servicios de AngularJS
UsuarioRepository.$inject=['remoteDAOFactory'];
function UsuarioRepository(remoteDAOFactory) {
var usuarioRemoteDAO=remoteDAOFactory.getRemoteDAO("Usuario");
var promise=usuarioRemoteDAO.get(3);
}
Se llama a getRemoteDAO(entidad)
RemoteDAO.$inject = ['$http', 'entityName'];
function RemoteDAO($http, entityName) {
this.entityName=entityName
this.get = function (id) {
var promise=$http({
method:"GET",
url:"/api/" + entityName + "/" + id;
});
//Implementar el método
};
}
RemoteDAOFactory.$inject = ['$injector'];
function RemoteDAOFactory($injector) {
var remoteDAOs = {
};
this.getRemoteDAO = function (entityName) {
if (!remoteDAOs[entityName]) {
var locals = {
entityName: entityName
};
remoteDAOs[entityName] = $injector.instantiate(RemoteDAO,locals);
}
return remoteDAOs[entityName];
};
}
<--- Mi solución
Para el PUT y el DELETE /entidad/id
El DAOFactory es un "provider" de AngularJS
remoteDAOFactoryProvider.setExtendRemoteDAO("Usuario",['remoteDAO',function(remoteDAO) {
remoteDAO.deshabilitar=function(usuario) {
//Aqui el código específico del nuevo método del DAO
};
}]);
Añadimos el método "deshabilitar" al remoteDAO de Usuario
Cuando se cree un nuevo UsuarioRemoteDAO se llamará a la función para que pueda añadir los métodos que quiera al RemoteDAO
RemoteDAOFactory.$inject = ['$injector', 'extendRemoteDAO'];
function RemoteDAOFactory($injector, extendRemoteDAO) {
var remoteDAOs = {
};
this.getRemoteDAO = function (entityName) {
if (!remoteDAOs[entityName]) {
var locals = {
entityName: entityName
};
remoteDAOs[entityName] = $injector.instantiate(RemoteDAO,locals);
if (extendRemoteDAO[entityName]) {
var locals = {
remoteDAO: remoteDAOs[entityName]
};
$injector.invoke(extendRemoteDAO[entityName], undefined, locals);
}
}
return remoteDAOs[entityName];
};
}
Al crear el RemoteDAO llamamos a una función para que lo "extienda" como quiera
RemoteDAOFactoryProvider.$inject = ['$injector'];
function RemoteDAOFactoryProvider() {
var extendRemoteDAO = {
};
this.setExtendRemoteDAO = function (entityName, fn) {
extendRemoteDAO[entityName] = fn;
};
this.$get = ['$injector', function ($injector) {
var locals = {
extendRemoteDAO: extendRemoteDAO
};
return $injector.instantiate(RemoteDAOFactory, locals);
}];
}
RemoteDAO.$inject = ['$http', '$interpolate', 'entityName'];
function RemoteDAO($http, $interpolate, entityName) {
this.entityName=entityName
this.urlGet="/api/{{entityName}}/{{id}}";
this.urlGetExpression=$interpolate(this.urlGet);
this.get = function (id) {
var url=urlGetExpression({
entityName:this.entityName,
id:id
});
$http({
method:"GET",
url:url
});
//Implementar todo el método
};
}
remoteDAOFactoryProvider.setExtendRemoteDAO(
"Usuario",['remoteDAO','$interpolate',function(remoteDAO,$interpolate) {
remoteDAO.urlGet="/api/v2/{{entityName}}/{{id}}";
}]);
RemoteDAO.$inject = ['$http', '$interpolate', 'entityName'];
function RemoteDAO($http, $interpolate, entityName) {
this.entityName=entityName
this.urlGet="/api/{{entityName}}/{{id}}";
this.urlGetExpression=$interpolate(this.urlGet);
this.preGet=function() {};
this.postGet=function() {};
this.get = function (id) {
var url=urlGetExpression({
entityName:this.entityName,
id:id
});
this.preGet();
$http({
method:"GET",
url:url
});
this.postGet(); //OJO:Debe estar en la promesa
//Implementar todo el método
};
}
remoteDAOFactoryProvider.setExtendRemoteDAO(
"Usuario",['remoteDAO','$interpolate',function(remoteDAO,$interpolate) {
remoteDAO.postGet=function() {
alert("Leido usuario");
}
}]);
RemoteDAOFactory.$inject = ['$injector'];
function RemoteDAOFactory($injector) {
var remoteDAOs = {
};
this.getRemoteDAO = function (entityName) {
if (!remoteDAOs[entityName]) {
if ($injector.has(entityName + "RemoteDAO") {
remoteDAOs[entityName] = $injector.get(entityName + "RemoteDAO");
} else {
var locals = {
entityName: entityName
};
remoteDAOs[entityName] = $injector.instantiate(RemoteDAO,locals);
}
}
return remoteDAOs[entityName];
};
}
Si queremos personalizar el RemoteDAO de "Usuario" creamos el servicio "UsuarioRemoteDAO"
No he encontrado ninguna solución que sea:
buena, bonita y barata
:-(
Si sabes lo que estás haciendo puedes tener soluciones sencillas para la casuística de tu proyecto.
Es necesario enriquecer el DTO y obtener el modelo rico
var dtoUsuario1 = {
nombre: "Marcos",
ape1: "Salas",
ape2: "Lopez",
fechaNacimiento: 31548664546,
tipoUsuario: "ALUMNO"
};
var dtoUsuario2 = {
nombre: "Carlos",
ape1: "Diaz",
ape2: "Ortega",
fechaNacimiento: 64874654646,
tipoUsuario: "PROFESOR",
departamento: 3
};
var modelUsuario1 = {
nombre: "Marcos",
ape1: "Salas",
ape2: "Lopez",
getNombreCompleto: function () {
return this.nombre + " " + this.ape1 + " " + this.ape2;
},
fechaNacimiento: new Date(31548664546),
tipoUsuario: "ALUMNO"
};
var modelUsuario2 = {
nombre: "Carlos",
ape1: "Diaz",
ape2: "Ortega",
getNombreCompleto: function () {
return this.nombre + " " + this.ape1 + " " + this.ape2;
},
fechaNacimiento: new Date(64874654646),
tipoUsuario: "PROFESOR",
departamento: 3,
getNombreDepartamento: function () {
return departamentoService.getNombre(this.departamento);
}
};
app.config(['richModelProvider', function(richModelProvider) {
richModelProvider.addGlobalTransformer(function() {
var uniqueID=0;
return function (object) {
object.$uniqueID=uniqueID;
uniqueID++;
};
});
}]);
La primera función se ejecuta una única vez y después de la fase de configuración por lo que permite inyectar servicios. En ella se define una única vez lo que se va a enriquecer.La función que retorna es llamada para cada objeto a enriquecer
app.config(['richModelProvider', function(richModelProvider) {
richModelProvider.addEntityTransformer('Usuario',['departamentoService',function(departamentoService) {
function getNombreCompleto () {
return this.nombre + " " + this.ape1 + " " + this.ape2;
}
function getNombreDepartamento () {
return departamentoService.getNombre(this.departamento);
}
return function (object) {
object.getNombreCompleto = getNombreCompleto;
if (object.tipoUsuario === "PROFESOR") {
object.getNombreDepartamento = getNombreDepartamento;
}
object.fechaNacimiento = new Date(objeto.fechaNacimiento);
};
}]);
}]);
¡No queremos repetir código ni preocuparnos por las relaciones!
var modelUsuario2 = {
nombre: "Carlos",
ape1: "Diaz",
ape2: "Ortega",
getNombreCompleto: function () {
return this.nombre + " " + this.ape1 + " " + this.ape2;
},
fechaNacimiento: new Date(64874654646),
tipoUsuario: "PROFESOR",
departamento: 3,
getNombreDepartamento: function () {
return departamentoService.getNombre(this.departamento);
},
centro: {
codigo:"46567",
nombre:"CIFP Mislata",
getCodigoProvincia: function() {
return this.codigo.substring(0,2);
}
}
};
var modelAula = {
nombre:"2A5",
piso:2,
centro: {
codigo:"46567",
nombre:"CIFP Mislata",
getCodigoProvincia: function() {
return this.codigo.substring(0,2);
}
}
};
Hay que repetir el código en cada sitio donde aparece una misma entidad
app.config(['richModelProvider', function(richModelProvider) {
richModelProvider.addEntityTransformer('Usuario',function() {
function getCodigoProvincia() {
return this.codigo.substring(0,2);
}
return function (object) {
object.centro.getCodigoProvincia=getCodigoProvincia;
};
});
}]);
Conocer la relación entre Usuario y Centro
app.config(['richModelProvider', function(richModelProvider) {
richModelProvider.addEntityTransformer('Aula',function() {
function getCodigoProvincia() {
return this.codigo.substring(0,2);
}
return function (object) {
object.centro.getCodigoProvincia=getCodigoProvincia;
};
});
}]);
Conocer la relación entre Aula y Centro
app.config(['richModelProvider', function(richModelProvider) {
richModelProvider.addEntityTransformer('Centro',function() {
function getCodigoProvincia() {
return this.codigo.substring(0,2);
}
return function (object) {
object.getCodigoProvincia=getCodigoProvincia;
};
});
}]);
Enriquecer directamente la entidad "Centro"
Desde la parte Servidora (Java) si que tengo tipos así que mis JSON siempre incluyen el nombre de la clase
var modelUsuario2 = {
nombre: "Carlos",
ape1: "Diaz",
ape2: "Ortega",
fechaNacimiento: 64874654646,
tipoUsuario: "PROFESOR",
departamento: 3,
$className:"Usuario",
centro: {
codigo:"46567",
nombre:"CIFP Mislata",
$className:"Centro"
}
};
var modelAula = {
nombre:"2A5",
piso:2,
$className:"Aula",
centro: {
codigo:"46567",
nombre:"CIFP Mislata",
$className:"Centro"
}
};
Ya puedo enriquecer "Centro" independientemente de donde esté
app.config(['richModelProvider', function(richModelProvider) {
richModelProvider.addEntityTransformer('Usuario',function() {
$validators: [
{
propertyName: function() {
return "confirmPassword"
},
message: 'El valor de {{password}} no es igual al de {{confirmPassword}}',
rule: function () {
if (this.password === this.confirmPassword) {
return true;
} else {
return false;
}
}
}
]
return function (object) {
object.$validators=$validators;
};
});
}]);
Yo uso Repository para dejar limpio Service para que se pueda modificar libremente
Mas en: http://www.cursoangularjs.es
By Lorenzo Gonzalez Gascón
I'm teacher in computer Science in a high school, the high school is named "CIPFP Mislata" in Spain-Valencia-Mislata .