让 Grails 控制器更加 DRY?
我正在寻找清理 Grails 控制器代码的方法。在各种控制器中,我或多或少具有相同的逻辑..
- 获取对象
- 检查它是否存在
- 等..
是否有建议的方法使控制器操作重用通用代码?
--- 解决方案 ---
问题的所有答案都有助于我们实施的解决方案。
我们使用 Mixin 方法创建了一个在控制器中使用的类。 mixin 公开的方法之一是 withObject 方法。此方法从控制器获取域名并将其用作该方法的基础。当然可以覆盖此行为!
def withObject(object=this.getClass().getName()-"Controller", id="id", Closure c) {
assert object
def obj = grailsApplication.classLoader.loadClass(object).get(params[id])
if(obj) {
c.call obj
} else {
flash.message = "The object was not found"
redirect action: "list"
}
}
所以所有的答案都有助于解决问题!多谢!
I am looking for ways on how to cleanup my Grails controller code. In various controllers i more or less have the same logic..
- get the object
- check if it exists
- etc..
Is there a suggested way on making controller actions reuse common code?
--- solution ---
All answers to the question have contributed to the solution we have implemented.
We created a class that is used in our controllers using the Mixin approach. One of the methods that the mixin exposes is the withObject method. This method takes the domainname from the controller and uses this a base for the method. This behaviour can be overridden of course!
def withObject(object=this.getClass().getName()-"Controller", id="id", Closure c) {
assert object
def obj = grailsApplication.classLoader.loadClass(object).get(params[id])
if(obj) {
c.call obj
} else {
flash.message = "The object was not found"
redirect action: "list"
}
}
So all answers have contributed to the solution! Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当这个问题出现时,我总是拿出这篇博客文章:
http://mrpaulwoods.wordpress.com/2011/01/23/a-pattern-to-simplify-grails-controllers/
基本上你在控制器中为各个域提供一个私人助手。
对getter 进行编码的方式非常灵活,对我来说(博客中未介绍)的典型用途是编辑等。
这种方式进行编码(我喜欢这种模式,因为它具有清晰的划分和可读性):
我通常以 helper 是:
我确实认为 mixin 方法(与“扩展通用抽象控制器”方式非常相似)也很好,但这种方式有两个优点:
在我绑定到 edit() 的视图中,我只是放置了一个
中的id="${issue.id}"
并且可以无缝运行。I always pull out this blog post when this question comes up:
http://mrpaulwoods.wordpress.com/2011/01/23/a-pattern-to-simplify-grails-controllers/
Basically you have a private helper for various domains in your controllers.
The way you code the getter is very flexible and a typical use for me (that is not covered in the blog) is for editing etc.
I normally code this way (i like the pattern for its clear division and readability):
With my getter helper being:
I do think that the mixin method (very similar to the 'extend a common abstract controller' way) is nice too, but this way gives two advantages:
In the view I bind to edit() I just put an
id="${issue.id}"
in the<g:form>
and it works seamlessly.我不建议为此使用继承,因为您不能在多个超类中传播通用方法。如果您有很多控制器,您的抽象类很快就会变得混乱。您无法使用组合(例如使用服务),因为您无法直接从以下位置访问
response
、render
或params
那里。我使用的方法是通过 Mixins 注入通用方法。
第一个操作
show
使用ControllerGenericActions.groovy
中的通用方法,并绑定了一个参数。 mixin idExists 方法的第二次使用是在控制器操作内部。下面是 src/groovy/ControllerGenericActions.groovy
和 src/groovy/ControllerUtil.groovy 中
的示例代码,在这种情况下不是很有用,但您明白了。
I wouldn't recommend inheritance for that, as you can't spread generic methods in several super classes. Your abstract class would quickly become messy if you have many controllers. You can't use composition (for instance using a Service) because you don't have access to
response
,render
, orparams
directly from there.The approach I use is to inject generic methods via Mixins.
The first action
show
uses a generic method inControllerGenericActions.groovy
, with an argument binded to it. The second use of a mixinidExists
method is inside a controller action.Here is an example code for
src/groovy/ControllerGenericActions.groovy
and in
src/groovy/ControllerUtil.groovy
Not very useful in this case, but you get the idea.
使用通用方法实现抽象控制器(使用“受保护”指令)并从中扩展您的真实控制器。不要在此方法名称的开头使用“get”和“set”单词。不好,但它有效。
Implement abstract controller with common methods (use 'protected' directive) and extend from it your real controllers. Do not use 'get' and 'set' words at the beginning of this method's names. Not good, but it works.