【问题标题】:How to use transients domain attributes with Grails Fields Plugin如何通过 Grails Fields 插件使用瞬态域属性
【发布时间】:2013-08-20 16:54:44
【问题描述】:

我正在尝试将字段确认密码添加到用户注册表单。这是我的域类的摘录:

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 可以吗?在客户端或服务器端测试的条件在哪里? (我认为部分检查在客户端,但所有限制都在服务器端再次检查)。

【问题讨论】:

  • 嗯,不应该是:&lt;f:field bean="${usuarioInstance}" property="confirmarPassword" /&gt;
  • 那行代码同样的问题:Property [confirmarPassword] of class [class usuario.Usuario] with value [null] does not pass custom validation :/

标签: grails grails-plugin


【解决方案1】:

哦,我以前也遇到过。

声明

        String confirmarPassword

并使它像这样对我不起作用

        static transients = ['confirmarPassword']

但是

        transient  confirmarPassword 

正如您为 springService 所做的那样......我现在不知道为什么这不起作用,这个,有人可能有更好的说明......

【讨论】:

  • 如果我将 static transients = ['confirmarPassword'] 更改为 transients confirmarPassword,eclipse 会显示编译器错误:Groovy:unexpected token: transients @ line 30, column 2
  • 第二个选项怎么样,我希望它有效?> 可以将其声明为“瞬态确认密码”
  • 我不明白。第二个选项是什么意思?
  • 你是否删除了's'形式的transients并用作transient ConfirmarPassword?
  • 我更新了我的答案(并检查它是否正确)。如果它对某人有用,我会很高兴! :)
【解决方案2】:

在最新版本的 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'
    }
}

但是,&lt;f:all bean="usuarioInstance"/&gt; 不会显示瞬态属性,我们必须手动添加这些属性:&lt;f:field bean="${usuarioInstance}" property="confirmarPassword" /&gt;。这不是一个理想的解决方案。我会保留这个问题几天,希望有人知道答案。

更新

就我而言,上述解决方案也不起作用,因为我使用的是 Spring Security Core 插件。它给出了下一个错误:

usuario.Usuario 条目中的空 id(发生异常后不要刷新 Session)

在这种情况下,我们必须使用command object。该问题在this post中进行了描述(并已解决)。

【讨论】:

    猜你喜欢
    • 2011-07-20
    • 2011-09-16
    • 1970-01-01
    • 2014-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-23
    相关资源
    最近更新 更多