在grails中的控制器操作之间传递对象的最佳方法

时间:2012-03-17 15:28:23

标签: spring html5 grails groovy

我想要一个链接在我的webapp中打开另一个视图,以显示有关指定对象的信息。 在grail中控制器动作之间传递对象的最佳方法是什么?

3 个答案:

答案 0 :(得分:4)

可以使用chain controller method链接操作。

链接允许模型从一个动作保留到下一个动作。

答案 1 :(得分:0)

(晚会,但是......)我正在使用Grails 2.4.4,它允许我执行以下操作:

def usernameLogin() {
  SecurityToken securityToken = authService.loginWithUserPass(params.user, params.pass)
  chain action: 'afterLogin', model: [securityToken: securityToken]
}

def ssoLogin() {
  SecurityToken securityToken = authService.ssoLogin(params.remoteUser, params.key)
  chain action: 'afterLogin', model: [securityToken: securityToken]
}

def afterLogin() {
  SecurityToken securityToken = (SecurityToken) chainModel['securityToken']
  if (securityToken.valid) {
    forward action: 'loggedInRedirect'
  }
  else {
    forward action: 'loginFailed'
  }
}
  • SecurityToken是一个包含字符串和枚举
  • 的对象
  • 关键是1)在源动作中使用“链动作”,2)在目标动作中使用chainModel

希望这有帮助。

答案 2 :(得分:0)

早期的答案不完整。所以,我正在编写它们以及我的输入并使它们更清晰。

您有两种选择:

  1. 链接行动:

    def action1() = {
        DomainClass domainInstance = DomainClass.findById(params.id);
        chain (action: 'action2', model: [domainInstance: domainInstance]); 
    }
    
    def action2() = {
        DomainClass domainInstance = chainModel?.domainInstance ?: DomainClass.findById(params.id);
        [domainInstance: domainInstance]; 
    }
    

    然而,后续行动似乎使用了新的数据库会话 而不是重复使用前一个(也可能是 可以在Grails中配置,我不知道如何)。所以任何懒惰 加载的实体可能无法在后续操作中完全加载 可能会给出LazyInitializationException(当然,这取决于你的ORM配置)。

  2. 转发请求:

    def action1() = {
        DomainClass domainInstance = DomainClass.findById(params.id);
        forward (action: 'action2', model: [domainInstance: domainInstance]); 
    }
    
    def action2() = {
        DomainClass domainInstance = request?.domainInstance ?: DomainClass.findById(params.id);
        [domainInstance: domainInstance]; 
    }
    
  3. 与前一种情况不同,请求转发会重用现有会话,因此不会发生延迟加载问题。

    如您所见,两者的语法几乎完全相同。但是,由于上述问题,应该根据相关要求更喜欢请求转发。另一个重要细节是关于在页面加载后的地址栏中查看的URL。转发请求将保留页面URL,同时链接操作会将页面URL更改为最新操作的URL。