设置全局变量并在Grails控制器中访问它们

时间:2011-11-02 07:00:06

标签: grails groovy

这可能是一个基本问题,但我是grails的新手,并试图寻找解决方案。 我需要在我的groovy控制器中有一个全局变量,例如一个列表,它在一个闭包(def)中更新,其值在该def中更新, 列表的这个新值应该在其他closure / def中可用。 我试过简单地说:

class MyController {
  def myList = []

  def def1 = { myList = someList.clone();}

  def def2 = { println myList}
}

myList的值应显示为def1的更新值,现在它保持为空。 static会有帮助吗?或者是否有一种方法可以直接在闭包之间传递变量,因为我不希望将大型列表传递给GSP并返回第二个def

2 个答案:

答案 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内部已正确更新。请记住,此全局性仅限于用户会话,其中包含有关用户会话的所有限制。但这是正确的,因为在用户使用系统之前,用户会话是全局的,并且与同时使用它的所有其他用户保持分离。如果同一个用户获得另一个会话,则会丢失这些值。