Scaffolding
什么是 Scaffolding?
Scaffolding让你可以自动为一个域对象生成整个应用,包括:
启用 Scaffolding
最简单的使用scaffolding的方法是使用"scaffold"属性,以"Book"这个对象为例,你需要在一个控制器(Controller)里把"scaffold"这个属性设置为true就可以了:
class BookController {
def scaffold = true
}
上面的代码能工作是因为BookController和Book这个域对象遵循了同样的命名规范,如果我们需要scaffold一个指定的域对象,可以直接在scaffold这个属性里指定:
def scaffold = Author.class
这就可以了!如果你运行这个应用,需要的操作和视图会在运行时自动产生,运行时scaffolding机制会动态的实现以下的操作:
- list
- show
- edit
- delete
- create
- save
- update
将会自动产生类似以下的界面:

如果你喜欢用java来写你的域对象并使用hibernate映射,你仍然可以使用scaffolding,很简单,只需要import这个类并设置在scaffold属性里就可以了。
动态 Scaffolding
因为Grails并不是使用代码模板来生成这些代码,因此你可以在使用scaffolding的控制器里添加你自己的操作,并可以和scaffolding自动生成的操作进行交互。例如,在下面的示例中,changeAuthor 这个操作将会重定向到show这个操作去:
class BookController {
def scaffold = Book.class
def changeAuthor = {
def b = Book.get( params["id"] )
b.author = Author.get( params["author.id"] )
b.save()
// redirect to a scaffolded action
redirect(action:show)
}
}
如果有必要的话你还可以覆盖掉自动产生的操作,如:
class BookController {
def scaffold = Book.class
// overrides scaffolded action to return both authors and books
def list = {
[ "books" : Book.list(), "authors": Author.list() ]
}
}
生成控制器和视图
上面的scaffolding演示很有用,但是在实际情况中,你一般都需要修改一些逻辑和视图.Grails允许你使用命令行生成产生上述效果的控制器和视图,要生成一个控制器,只需要:
grails generate-controller
或者生成视图:
grails generate-views
或者生成所有的东西:
grails generate-all
所有这些命令都会提示你输入域对象的名字,你甚至可以为用java写的并由自己映射到hibernate的域对象生成相应的控制器和视图!
修改生成的视图
Grails生成的视图比较智能,他能自动适应数据校验的规则。例如你可以通过修改校验规则中的顺序来调整字段出现的顺序:
def constraints = {
title()
releaseDate()
}
你还可以使用inList来让生成器生成一个list而不是普通的输入框:
def constraints = {
title()
category(inList:["Fiction", "Non-fiction", "Biography"])
releaseDate()
}
或者,你可以在数字上使用限制:
def constraints = {
age(range:18..65)
}
限制一个字段的长度将会影响到产生的视图中能输入多少个字符:
def constraints = {
name(length:0..30)
}
你还可以使用"widget"来修改普通的input输入框为textarea:
def constraints = {
description(widget:'textarea')
}
与Java的集成
如果你的域对象是用java写的并映射到hibernate,你仍然可以使用grails的scaffolding机制带来的好处,本文假设你已经阅读过grails和hibernate是如何集成的相关章节GORM,scaffold一个hibernate域对象你只需要在控制器里引用他:
import com.books.HibernateBook
class BookController {
def scaffold = HibernateBook.class
}
你仍然可以为hibernate的域对象生成控制器和视图,不过你得输入完整的包名+类名。
如果需要集成到grails的数据校验机制并生成相应的视图,你可以遵循命名规范"域对象名+Constraints"为你的域对象提供一个groovy脚本。例如,要为HibernateBook这个类定义数据校验规则,你需要创建一个名为"com/books/HibernateBookConstraints.groovy"的脚本,注意包的名字要和域对象的包名一致。这样你就可以按GORM的做法定义的你规则了,不过不需要在名字前不需要加def这个关键字了:
constraints = {
title(length:5..15)
desc(blank:false)
}