【发布时间】:2012-03-17 15:28:23
【问题描述】:
我想要一个链接以在我的 web 应用程序中打开另一个视图以显示有关指定对象的信息。 在 grail 中的控制器动作之间传递对象的最佳方式是什么?
【问题讨论】:
我想要一个链接以在我的 web 应用程序中打开另一个视图以显示有关指定对象的信息。 在 grail 中的控制器动作之间传递对象的最佳方式是什么?
【问题讨论】:
可以使用chain controller method 链接操作。
链接允许模型从一个动作保留到下一个动作。
【讨论】:
之前的答案不完整。因此,我将它们与我的输入一起编译并使其更清晰。
你有两个选择:
链接操作:
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 配置)。
转发请求:
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];
}
与前一种情况不同,请求转发重用现有会话,因此不会出现延迟加载问题。
如您所见,两者的语法几乎相同。但是由于上述问题,人们应该更喜欢根据相关要求转发请求。另一个重要的细节是关于在页面加载时/之后在地址栏中查看的 URL。转发请求将保留页面 URL,而链接操作会将页面 URL 更改为最新操作的 URL。
【讨论】:
(迟到了,但是...)我使用的是 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'
}
}
希望这会有所帮助。
【讨论】: