【问题标题】:Grains repetead code for actions in controllers为控制器中的操作提供重复代码
【发布时间】:2011-06-14 11:23:32
【问题描述】:

我已经发布了这个问题,但我意识到这个问题不是我想要的。想象一下这个控制器:

    class exampleController{

    def action1 = {
           ...

[lala: lala, lele: lele]}

           ...
    }
    def action15 = {
           ...

[lala: lala, lele: lele]

}

我希望能够在此控制器中的所有操作中返回相同的参数。想象一下:

def book = Book.findAllByIsbn(Isbn.get(1))  
[book: book]

除了在所有动作上编写所有相同的代码之外,还有什么方法可以做到这一点?这个方法我试过了,还是不行:

def action5 = {getModel()}

  private getModel() {
    def book = Book.findAllByIsbn(Isbn.get(1))  
[book: book]  
  }
}

它不起作用,因为我的想法是,他不接受多个 [return1: aaa, return2: bbb]。请问有什么建议吗?我也尝试过像这里这样的过滤器:Grails controllers repeated code for all actions 但我无法让它发挥作用。如果可能的话,我会对任何解决方案进行详细的解释:p 在此先感谢, 弗吉尼亚州

【问题讨论】:

  • 您的问题是如何为不同的控制器操作重用一种方法或闭包?
  • 再说一次,谁'他'不接受多个什么? getModel() 函数实际上可以 return 具有多个值的 Map,这看起来完全符合您的需要。
  • @Ruben 基本上,我希望能够在该控制器的所有操作中使用重复该代码。随心所欲地调用它
  • 想象我的动作已经有这样的东西 [fav: fav, par: par]。然后我调用 getModel()。出于某种原因,我不知道为什么,它不起作用,但如果我手动复制代码并加入两个 [..] [..] 返回它确实有效,我想弄清楚

标签: grails filter controller action


【解决方案1】:

所以不是同一个模型,而是有重复部分的模型。

你应该知道返回值是一个普通的Map

所以,返回值可以像return getCommonModel() + [book: currentBook] 这样构造,其中getCommonModel() 返回另一个 Map。

【讨论】:

    【解决方案2】:

    如果您想从所有操作中返回相同的模型,这种方法应该可行:

    class ExampleController {
    
      def action5 = {getModel()}
      def action1 = {getModel()}
      //etc.
    
      private getModel() {
        def book = Book.findAllByIsbn(Isbn.get(1))  
        [book: book]  
      }
    }
    

    如果您想返回相同的模型从您的所有操作中呈现相同的视图,您可以从每个操作中返回相同的ModelAndView,但我会问您为什么需要单独如果他们都在做完全相同的事情,他们会采取什么行动?

    我不太明白你的假设

    它不起作用,因为我的想法是,他不接受多个[return1: aaa, return2: bbb]

    如果您建议 getModel() 只能返回一个具有单个条目的模型,我觉得这很难相信。您能否详细说明一下,或发布更多信息(例如堆栈跟踪、单元测试)来说明它如何/为什么不起作用?

    更新

    在阅读了您下面的 cmets 之后,我想我终于明白了您想要实现的目标,即将getModel()(上)返回的模型附加到其他各种操作返回的模型中。这行得通吗:

    class ExampleController {
    
      def action5 = {
        def action5Model = [foo: 'bar']
        return addBookModel(action5Model)
      }
    
      def action1 = {
        def action1Model = [foo2: 'bar2']
        return addBookModel(action1Model)
      }
      //etc.
    
      private Map addBookModel(Map model) {
        def book = Book.findAllByIsbn(Isbn.get(1))  
        model.book = book
        return model
      }
    }
    

    仅当您想在单个控制器中添加图书模型时,此方法才有效。如果您想在多个控制器中添加图书模型,您可以通过以下方式执行此操作:

    • addBookModel 放入控制器扩展的抽象类中
    • addBookModel 放入与控制器混合的类中(使用@Mixin
    • addBookModel 放入在控制器操作之后执行的过滤器中

    【讨论】:

    • 当然,我会尽力解释得更好。我的网站中有严格的页面,在这两个页面中我都需要访问 ${book} 参数。所以,基本上并以艰难的方式做到这一点,我会将所有这些代码: def book = Book.findAllByIsbn(Isbn.get(1)) 复制到所有控制器,然后将这个: [book: book] 与在每个单独的操作中返回的其他参数。问题是,这不是一件容易的事,因为我的操作比这复杂得多,我会迷失在所有重复的代码中。我已经尝试过你的 iniccial aproach (getModel()) 事情,但由于某种原因它不起作用
    • 我在 action1 中尝试过类似的操作:def author = Author.get(1) getModel() [author: author]。虽然我可以在我的 gsp 页面中访问“作者”,但我没有访问权限,这是我的主要问题。如果我手动复制代码并混合参数,它可以工作
    • 找到了答案。而不是 getModel() 不会返回我想要的值,我这样做了: [ret: ret, ret2: getModel().book] 并且知道它正在工作。无论如何,感谢您的回答和与我共度的时间。
    • 是的,它有效,非常感谢:p 就我而言,我发现@victor 的回答更容易。谢谢
    • 其实我的回答和他的差不多:)
    【解决方案3】:

    如果您在多个页面中使用完全相同的模型。我建议您使用 taglib。

    【讨论】:

      猜你喜欢
      • 2011-09-10
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多