Grails-command-databinding-p4
Vista con N paneles, un command object para cada panel.
Dónde aplicar
Un command object que tiene las mismas propiedades que su domain class y se desea sacar la lógica de validación de la capa vista del domain class.
Características:
En base al panel que envíe el usuario, se deben validar unas u otras propiedades. No tiene sentido implementar esta lógica en el domain class porque además de la vista los constraints aplicarían para la base de datos lo cual es incorrecto porque los datos en la bd no se guardan por "paneles".
Cuando hay errores de validación en un panel, los demás paneles conservan sus valores originales.
A pesar de modificar datos de otros paneles, sólo se actualizará el panel que actualice el usuario.
Ventajas:
static constraints {}
.Desventajas
class ParamsController {
// envía a la página para editar los parámetros generales
def edit() {
return [paramsInstance: Params.getInstance()]
}
@Transactional
def update(String panelClassName, Long id) {
// Crear el panel indicado, asignar los valores del request y validar sus
// datos de acuerdo a la lógica definida en cada panel concreto.
def panel = GrailsUtils.newInstance(panelClassName)
bindData(panel, params) // request(params)->command object
panel.validate() // validar command object
// Es necesario pasar los valores del command object hacia el domain object
// porque el domain object se enviará de vuelta para mostrar los valores
// originales y los valores capturados incorrectamente junto con sus errores.
def paramsInstance = Params.read(id)
bindData(paramsInstance, panel)
paramsInstance.errors = panel.errors//command.errors to domain.errors
if (paramsInstance.hasErrors()) {
render view: 'edit', model: [paramsInstance: paramsInstance]
return
}
paramsInstance.save(failOnError: true)
flash.message = message(code: 'params.edit.success')
redirect action: "edit"
}
}
<g:form method="post" class="form-horizontal" role="form" action="update">
<g:hiddenField name="panelClassName" value="${us.incorpora.sigrem.PanelGeneral.name}" />
<g:hiddenField name="id" value="${paramsInstance.id}"/>
<div class="box-body">
<g:render template="formGeneral"/>
</div>
<div class="box-footer">
%{--Actualizar--}%
<t:onceSubmit name="submit1" class="btn btn-default pull-right">
<i class="fa fa-save fa-2x"></i> </br>
<g:message code="default.button.update.label"/>
</t:onceSubmit>
</div>
</g:form>
@Validateable
class PanelGeneral {
String emailContactoHotel
static constraints = {
emailContactoHotel email: true
}
}
@Validateable
class PanelConekta {
boolean productionMode
// obligatorio
String sandboxPrivateKey
// obligatorio
String sandboxPublicKey
String prodPrivateKey
String prodPublicKey
static constraints = {
// (obligatorio cuando el modo producción es on, opcional cuando es off)
prodPrivateKey(validator: { value, _this ->
if (_this.productionMode && !value) {
return "default.blank.message"
}
}, nullable: true)
// (obligatorio cuando el modo producción es on, opcional cuando es off)
prodPublicKey(validator: { value, _this ->
if (_this.productionMode && !value) {
return "default.blank.message"
}
}, nullable: true)
}
}
@Validateable
class PanelFinanzas {
// obligatorio
BigDecimal tipoCambio
// obligatorio
BigDecimal costoPunto
}