Model view controller 如何在不同的grails控制器中共享通用方法?
目前,当我需要在不同的控制器之间共享类似于Model view controller 如何在不同的grails控制器中共享通用方法?,model-view-controller,grails,grails-controller,Model View Controller,Grails,Grails Controller,目前,当我需要在不同的控制器之间共享类似于processParams(params)的方法时,我使用继承或服务。 这两种解决方案都有一些不便之处: 对于继承,您不能使用多重继承,这意味着您需要将所有控制器实用程序方法放在一个位置。此外,grails中还有一个bug,在开发模式下无法检测到基本控制器类中的任何代码更改(您需要重新启动应用程序) 使用服务,您无法访问所有注入的属性,如参数、会话、刷新 所以我的问题是:有没有其他方法可以使用一些可供多个控制器访问的常用方法?这无助于解决在开发模式下
processParams(params)
的方法时,我使用继承或服务。
这两种解决方案都有一些不便之处:
- 对于继承,您不能使用多重继承,这意味着您需要将所有控制器实用程序方法放在一个位置。此外,grails中还有一个bug,在开发模式下无法检测到基本控制器类中的任何代码更改(您需要重新启动应用程序)
- 使用服务,您无法访问所有注入的属性,如参数、会话、刷新
所以我的问题是:有没有其他方法可以使用一些可供多个控制器访问的常用方法?这无助于解决在开发模式下重新启动的问题,但这是我解决这个问题的方法。这很难看,可能不是好的做法,但我将公共代码作为闭包考虑到类中。然后我可以做一些类似的事情:
new ControllerClosures().action(this)
从controllerClosures类中的
def action={
it.response.something
return [allYourData]
}
您可以使用:
对于控制器,请直接在实例字段(或空构造函数)中分配帮助器类:
的类型信息被编译到包含类中。我喜欢的一个选项是将常用方法作为一个类别编写,然后根据需要将其混合到控制器中。它比继承提供了更多的灵活性,可以访问params之类的东西,代码简单易懂 这里有一个小例子:
@Category(Object)
class MyControllerCategory {
def printParams() {
println params
}
}
@Mixin(MyControllerCategory)
class SomethingController {
def create = {
printParams()
...
}
def save = {
printParams()
}
}
公共功能是对新类的调用,而不一定是对公共祖先的调用。问题表述缺少对其的责任陈述。不用说,我们为其创建一个新类是一项单独的责任。我会根据班级责任做出进一步的决定 我更喜欢混合使用Robbert和Jared的答案:我构造额外的类,将必要的控制器内部作为参数传递给它们。有时,课程是从一开始发展起来的。 比如: 不那么简单,但可以让您在测试中获得代码并保持低耦合 由于
SomeResponsibilityDoer
只会有几个字段-请求一个响应-用每个请求构造它并不是什么大问题
在dev中更改控制器时不重新加载SomeResponsibilityDoer
也没什么大不了的,因为:
src/groovy
您可以在commonService中编写所有常用方法
并将该服务用于envoke commmon method委托类无权访问所有者类的内部,例如render方法或params。不幸的是,这是事实,因此在这种情况下,
@delegate
将不是选择的方法。实际上,使用@Mixin
注释不需要@Category
注释。-只有在使用替代方法SomethingController.mixin([MyControllerCategory])
时才需要它(这需要MyControllerCategory
提供一个static
方法printParams()
)。Groovy文档提供了与您类似的示例,但这不是必需的。-这种误解可能是因为类别的使用经历了一个进化过程——曾经语法笨拙,现在被@Mixin
注释所取代。最后,@Mixin
和@Delegate
之间的主要区别在于委托方法是静态编译到目标类中的,而Mixin方法是在运行时调用的。有没有办法使MyControllerCategory
服从依赖项注入?如果使用此模式,并使用Spock运行问题测试,如果混合类在Spock测试之间重置,请在此处查看解决方案:traits
正在替换@Mixin
,而@Mixin
已被Groovy 2.3弃用。更多关于特质的信息:&
class HelperClass {
def renderFoo() { render 'foo' }
}
class FooController {
private @Delegate HelperClass helperClass = new HelperClass()
def index = { this.renderFoo() }
}
@Category(Object)
class MyControllerCategory {
def printParams() {
println params
}
}
@Mixin(MyControllerCategory)
class SomethingController {
def create = {
printParams()
...
}
def save = {
printParams()
}
}
def action = {
def doer = SomeResponsibilityDoer(this.request, this.response)
render doer.action()
}