h4. Returning the Model
h4. 返回模型(Model)
A model is essentially a map that the view uses when rendering. The keys within that map translate to variable names accessible by the view. There are a couple of ways to return a model, the first way is to explicitly return a map instance:
模型(Model)本质上是个map类型,当视图(view)被渲染时使用。map中的keys转变成变量名让view(视图)访问。这里有一对方式来返回模型(Model),第一种方式是明确返回map实体:
{code:java}
def show = {
[ book : Book.get( params.id ) ]
}
{code}
If no explicit model is returned the controller's properties will be used as the model thus allowing you to write code like this:
假如没有明确的模型(Model)被返回,控制器的属性将被当做模型(Model)来使用,因此允许你的代码写成下面这样:
{code:java}
class BookController {
List books
List authors
def list = {
books = Book.list()
authors = Author.list()
}
}
{code}
{note}
This is possible due to the fact that controllers are prototype scoped. In other words a new controller is created for each request. Otherwise code such as the above would not be thread safe.
这可能是由于事实上控制器(Controllers)是prototype(原型)范围。换句话说,每次请求,一个新的控制器(Controllers)会被创建。否则上面的代码将不是线程安全的。
{note}
In the above example the @books@ and @authors@ properties will be available in the view.
在上面示例中的 @books@ 和 @authors@属性将在view(视图)中被使用。
A more advanced approach is to return an instance of the Spring [ModelAndView|api:org.springframework.web.servlet.ModelAndView] class:
一个更加高级的方法是返回Spring [ModelAndView|api:org.springframework.web.servlet.ModelAndView] 类。
{code:java}
import org.springframework.web.servlet.ModelAndView
...
def index = {
def favoriteBooks = ... // get some books just for the index page, perhaps your favorites
// forward to the list view to show them
return new ModelAndView("/book/list", [ bookList : favoriteBooks ])
}
{code}
h4. Selecting the View
h4.选择视图( View)
In both the previous two example there was no code that specified which [view:guide:GSP] to render. So how does Grails know which view to pick? The answer lies in the conventions. For the action:
在先前的两个示例里没有代码指定哪个 [view:guide:GSP]去渲染。那么Grails怎么知道哪个视图( View)被选取了?答案在于规约。观察这个Actions(操作):
{code:java}
class BookController {
def show = {
[ book : Book.get( params.id ) ]
}
}
{code}
Grails will automatically look for a view at the location @grails-app/views/book/show.gsp@ (actually Grails will try to look for a JSP first, as Grails can equally be used with JSP).
Grails 将自动在 @grails-app/views/book/show.gsp@ 位置寻找一个视图( View)(事实上 Grails将首先尝试寻找JSP页面, 因为Grails 可以等同的用于JSP).
If you wish to render another view, then the [render|controllers] method there to help:
假如你希望渲染另一个视图( View),那么[render|controllers]方法可以帮助你:
{code:java}
def show = {
def map = [ book : Book.get( params.id ) ]
render(view:"display", model:map)
}
{code}
In this case Grails will attempt to render a view at the location @grails-app/views/book/display.gsp@. Notice that Grails automatically qualifies the view location with the @book@ folder of the @grails-app/views@ directory. This is convenient, but if you have some shared views you need to access instead use:
在这种情况下Grails将尝试渲染 @grails-app/views/book/display.gsp@位置上的视图( View)。注意,Grails自动描述位于@book@文件夹中的 @grails-app/views@ 路径位置的视图( View)。很便利,但是假如你拥有一些共享的视图( View)用来存取,作为替代使用:
{code:java}
def show = {
def map = [ book : Book.get( params.id ) ]
render(view:"/shared/display", model:map)
}
{code}
In this case Grails will attempt to render a view at the location @grails-app/views/shared/display.gsp@.
在这种情况下Grails将尝试渲染@grails-app/views/shared/display.gsp@位置上的视图( View)。
Rendering a Response
渲染Response(响应)
Sometimes its easier (typically with Ajax applications) to render snippets of text or code to the response directly from the controller. For this the highly flexible "render" method can be used:
有时它很容易的渲染来自创建控制器(Controllers)小块文本或者代码的响应(通常使用Ajax应用程序)。因为使用了高度灵活的 "render"方法。
{code:java}
render "Hello World!"
{code}
The above code writes the text "Hello World!" to the response, other examples include:
上面的代码打印出"Hello World!" 响应,其他的示例包括:
{code:java}
// write some markup
render {
for(b in books) {
div(id:b.id, b.title)
}
}
// render a specific view
render(view:'show')
// render a template for each item in a collection
render(template:'book_template', collection:Book.list())
// render some text with encoding and content type
render(text:"<xml>some xml</xml>",contentType:"text/xml",encoding:"UTF-8")
{code}
h4. 返回模型(Model)
A model is essentially a map that the view uses when rendering. The keys within that map translate to variable names accessible by the view. There are a couple of ways to return a model, the first way is to explicitly return a map instance:
模型(Model)本质上是个map类型,当视图(view)被渲染时使用。map中的keys转变成变量名让view(视图)访问。这里有一对方式来返回模型(Model),第一种方式是明确返回map实体:
{code:java}
def show = {
[ book : Book.get( params.id ) ]
}
{code}
If no explicit model is returned the controller's properties will be used as the model thus allowing you to write code like this:
假如没有明确的模型(Model)被返回,控制器的属性将被当做模型(Model)来使用,因此允许你的代码写成下面这样:
{code:java}
class BookController {
List books
List authors
def list = {
books = Book.list()
authors = Author.list()
}
}
{code}
{note}
This is possible due to the fact that controllers are prototype scoped. In other words a new controller is created for each request. Otherwise code such as the above would not be thread safe.
这可能是由于事实上控制器(Controllers)是prototype(原型)范围。换句话说,每次请求,一个新的控制器(Controllers)会被创建。否则上面的代码将不是线程安全的。
{note}
In the above example the @books@ and @authors@ properties will be available in the view.
在上面示例中的 @books@ 和 @authors@属性将在view(视图)中被使用。
A more advanced approach is to return an instance of the Spring [ModelAndView|api:org.springframework.web.servlet.ModelAndView] class:
一个更加高级的方法是返回Spring [ModelAndView|api:org.springframework.web.servlet.ModelAndView] 类。
{code:java}
import org.springframework.web.servlet.ModelAndView
...
def index = {
def favoriteBooks = ... // get some books just for the index page, perhaps your favorites
// forward to the list view to show them
return new ModelAndView("/book/list", [ bookList : favoriteBooks ])
}
{code}
h4. Selecting the View
h4.选择视图( View)
In both the previous two example there was no code that specified which [view:guide:GSP] to render. So how does Grails know which view to pick? The answer lies in the conventions. For the action:
在先前的两个示例里没有代码指定哪个 [view:guide:GSP]去渲染。那么Grails怎么知道哪个视图( View)被选取了?答案在于规约。观察这个Actions(操作):
{code:java}
class BookController {
def show = {
[ book : Book.get( params.id ) ]
}
}
{code}
Grails will automatically look for a view at the location @grails-app/views/book/show.gsp@ (actually Grails will try to look for a JSP first, as Grails can equally be used with JSP).
Grails 将自动在 @grails-app/views/book/show.gsp@ 位置寻找一个视图( View)(事实上 Grails将首先尝试寻找JSP页面, 因为Grails 可以等同的用于JSP).
If you wish to render another view, then the [render|controllers] method there to help:
假如你希望渲染另一个视图( View),那么[render|controllers]方法可以帮助你:
{code:java}
def show = {
def map = [ book : Book.get( params.id ) ]
render(view:"display", model:map)
}
{code}
In this case Grails will attempt to render a view at the location @grails-app/views/book/display.gsp@. Notice that Grails automatically qualifies the view location with the @book@ folder of the @grails-app/views@ directory. This is convenient, but if you have some shared views you need to access instead use:
在这种情况下Grails将尝试渲染 @grails-app/views/book/display.gsp@位置上的视图( View)。注意,Grails自动描述位于@book@文件夹中的 @grails-app/views@ 路径位置的视图( View)。很便利,但是假如你拥有一些共享的视图( View)用来存取,作为替代使用:
{code:java}
def show = {
def map = [ book : Book.get( params.id ) ]
render(view:"/shared/display", model:map)
}
{code}
In this case Grails will attempt to render a view at the location @grails-app/views/shared/display.gsp@.
在这种情况下Grails将尝试渲染@grails-app/views/shared/display.gsp@位置上的视图( View)。
Rendering a Response
渲染Response(响应)
Sometimes its easier (typically with Ajax applications) to render snippets of text or code to the response directly from the controller. For this the highly flexible "render" method can be used:
有时它很容易的渲染来自创建控制器(Controllers)小块文本或者代码的响应(通常使用Ajax应用程序)。因为使用了高度灵活的 "render"方法。
{code:java}
render "Hello World!"
{code}
The above code writes the text "Hello World!" to the response, other examples include:
上面的代码打印出"Hello World!" 响应,其他的示例包括:
{code:java}
// write some markup
render {
for(b in books) {
div(id:b.id, b.title)
}
}
// render a specific view
render(view:'show')
// render a template for each item in a collection
render(template:'book_template', collection:Book.list())
// render some text with encoding and content type
render(text:"<xml>some xml</xml>",contentType:"text/xml",encoding:"UTF-8")
{code}