这可能是一个基本问题,但我是grails的新手,并试图寻找解决方案。 我需要在我的groovy控制器中有一个全局变量,例如一个列表,它在一个闭包(def)中更新,其值在该def中更新, 列表的这个新值应该在其他closure / def中可用。 我试过简单地说:
class MyController {
def myList = []
def def1 = { myList = someList.clone();}
def def2 = { println myList}
}
myList
的值应显示为def1
的更新值,现在它保持为空。 static
会有帮助吗?或者是否有一种方法可以直接在闭包之间传递变量,因为我不希望将大型列表传递给GSP并返回第二个def
。
答案 0 :(得分:4)
您的控制器应保持无状态。控制器在每个操作请求中实例化,因此您的成员变量myList
将在操作之间被丢弃。如果您将其定义为静态,则它将由MyController
的所有实例共享。
如果定义myList
静态,则访问控制器的所有客户端都将获得相同的结果。如果这是您想要的,您的列表可能应该通过数据库中的域对象存储(see chapter 5 of Grails documentation, Object Relational Mapping)。
如果您希望每个客户在控制器操作之间共享自己的myList
,那么您要查找的内容称为网络流。它们提供了一种机制,用于在给定客户端执行的Controller操作之间存储状态。 Web流程记录在Grails documentation (Chapter 6 - The Web Layer)。
答案 1 :(得分:0)
当然,我完全赞同@antoine关于控制器的无状态。从广义上讲,MVC范式在编程中考虑变量的方式发生了很大变化:如果要保持值,则必须始终考虑GORM和DB。
无论如何,可能有一种有趣的替代方式来处理全球价值观;所有控制器操作以及服务的gloabal值:使用用户会话。例如:
Class MyController {
def myService
def act1 = {
session.myvalues = [:]
session.myvalues.myflag = true
...
myService.service1()
}
}
并在使用它的服务中
Class MyService {
def service1() {
def sess = RequestContextHolder.currentRequestAttributes().getSession()
if (sess?.myvalues?.myflag) println "Found true in myflag"
}
}
所以,我在用户会话中准备了一个名为" myvalues"的空地图。在里面我放了一面旗帜。然后我回到服务中的会话,我发现myflag内部已正确更新。请记住,此全局性仅限于用户会话,其中包含有关用户会话的所有限制。但这是正确的,因为在用户使用系统之前,用户会话是全局的,并且与同时使用它的所有其他用户保持分离。如果同一个用户获得另一个会话,则会丢失这些值。