我正在尝试将字段确认密码添加到用户注册表单中。这是我的域类的摘录:
package usuario
class Usuario {
transient springSecurityService
String password
String confirmarPassword
static constraints = {
password blank: false, password: true, size:5..15, matches:/[\S]+/
confirmarPassword blank:false, password: true, size:5..15, matches:/[\S]+/, validator:{ val, obj ->
if (obj.password != obj.confirmarPassword)
return 'usuario.password.dontmatch'
}
}
static transients = ['confirmarPassword']
static mapping = {
password column: '`password`'
}
Set<Rol> getAuthorities() {
UsuarioRol.findAllByUsuario(this).collect { it.rol } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
obj.confirmarPassword
始终为空,因此约束永远不会完成。
我按照建议here安装了Grails模板。我更改了属性persistentProperties
,但它仅位于_ form.gsp ,Grails Fields Plugins未使用_ form.gsp 。因此,瞬态属性不会出现在Internet浏览器中。
我将生成的_form.gsp瞬态属性复制到create.gsp:
<fieldset>
<g:form class="form-horizontal" action="create" >
<div class="fieldcontain ${hasErrors(bean: usuarioInstance, field: 'confirmarPassword', 'error')} required">
<label for="confirmarPassword">
<g:message code="usuario.confirmarPassword.label" default="Confirmar Password" />
<span class="required-indicator">*</span>
</label>
<g:field type="password" name="confirmarPassword" maxlength="15" pattern="${usuarioInstance.constraints.confirmarPassword.matches}" required="" value="${usuarioInstance?.confirmarPassword}"/>
</div>
<fieldset>
<f:all bean="usuarioInstance"/>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="icon-ok icon-white"></i>
<g:message code="default.button.create.label" default="Create" />
</button>
</div>
</fieldset>
</g:form>
</fieldset>
瞬态属性显示在屏幕上,但obj.confirmarPassword
仍为 null
我认为最后一种方法是修改 views_fields \ default_field.gsp 以使用这些瞬态属性,但我没有找到。这是the documentation。这是该文件的内容:
<%@ page defaultCodec="html" %>
<div class="control-group ${invalid ? 'error' : ''}">
<label class="control-label" for="${property}">${label}</label>
<div class="controls">
<%= widget %>
<g:if test="${invalid}"><span class="help-inline">${errors.join('<br>')}</span></g:if>
</div>
</div>
是否可以使用Grails Fields Plugin?在客户端或服务器端测试的条件在哪里? (我认为部分检查是在客户端,但是在服务器端再次检查所有限制。)
答案 0 :(得分:1)
在最新版本的Grails中,默认情况下,临时属性不与表单绑定。 This is the documentation of the bindable constraint。这就是我的代码将成为的方式(我刚刚添加了bindable: true
):
static constraints = {
password blank: false, password: true, size:5..15, matches:/[\S]+/
confirmarPassword bindable: true, blank:false, password: true, size:5..15, matches:/[\S]+/, validator:{ val, obj ->
if (obj.password != obj.confirmarPassword)
return 'usuario.password.dontmatch'
}
}
但是,<f:all bean="usuarioInstance"/>
不会显示瞬态属性,我们必须手动添加这些属性:<f:field bean="${usuarioInstance}" property="confirmarPassword" />
。这不是一个理想的解决方案。有些日子我会保持这个问题,希望有人知道答案。
<强>更新强>
在我的情况下,上述解决方案无法正常工作,因为我使用的是Spring Security Core插件。它给出了下一个错误:
usuario.Usuario条目中的null id(发生异常后不要刷新会话)
在这种情况下,我们必须使用command object 。 问题在this post 中进行了描述(并已解决)。
答案 1 :(得分:1)
哦,我以前遇到过它。
声明
String confirmarPassword
并使它成为traniset它不像我这样工作
static transients = ['confirmarPassword']
但是
transient confirmarPassword
正如你为springService所做的那样...我现在不知道为什么这不起作用,这个,有些人可能会有更好的澄清......