//Play FrameWork 2.0 Scala
requst --> routes -->Controller -->Action -->Result -->Html
play中的大多数请求都是有一个Action来处理的,当请求一个事件时,会由Routes规则进行匹配,交给相应的Controller,
Controller找到指定的Action,进行处理,并返回一个Result类型包含response体渲染页面
创建一个Action方法如:
def index = Action{//这里也可以使用 implicit request =>
//code
Ok("Hello")//一个简单的返回 [Result类型]
}
我们可以看看Action的定义
trait Action[A] extends (Request[A] => Result) {
def parser: BodyParser[A]
}
Request [A] 被定义为:
trait Request[+A] extends RequestHeader {
def body: A
}
[A] 是request body 的类型.我们可以使用任意Scala类型指定,例如 String、NodeSeq、Array[Byte]、JsonValue,或者java.io.File,只要我们有一个可以处理该类型的body parser.总而言之,一个 Action[A] 使用一个 BodyParser[A] 从HTTP请求中,取出一个A类型的值,并构建一个Request[A]对象,转递给action代码。
Controller是Actions的生成器,是产生Action的摸个单例对象.
Routes 可以在conf/routes里进行路由配置
==========================================================================
Form表单的一些知识
Form 位于play.api.data.Form下,创建一个表单如:
val helloForm = Form(
tuple( //也可以使用mapping
"name" -> nonEmptyText, //带验证的约束
"repeat" -> number(min = 1, max = 100),
"color" -> optional(text)
)
)
case class User(name: String, age: Int)
val userForm = Form(
mapping(
"name" -> text,
"age" -> number
)(User.apply)(User.unapply)
)
val anyData = Map("email" -> "bob@gmail.com", "age" -> "18")
val user: User = userForm.bind(anyData).get
注意:使用 tuple 和 mapping 的不同在于,当你使用 tuple 时,构造和析构不需要指定(我们知道怎样构造和解构一个tuple).
mapping 方法仅让你定义你的自定义函数。当你想构造和析构一个case class,你只不过是使用 apply 和 unapply 函数,它们能精确的做到.
当然,通常Form签名不会精确的匹配case class。让我们举个包含额外的 checkbox 字段标识是否接受服务条款的例子。我们不需要將checkbox属性加入User类中。
它只是为了表单验证而加入的一个虚拟字段,一旦验证通过,该值便毫无用处。
// helloForm.bindFormRequest.get 获取request中form表单值
def sayHello = Action{implicit request =>
helloForm.bindFromRequest.fold(// 处理并验证信息时的处理
formWithErrors => BadRequest(html.index(formWithErrors)),//出错并返回指定页面
{case (name,repeat,color)=> Ok(html.hello(name, repeat.toInt, color))}//正常
)
}
页面上的Form编写需要导入import helper._ 和使用@符号(x.scala.html中用到@时标记着scala代码开始加载)
@form(action=routes.Application.sayHello,'id ->"helloform",'method->"Post") {
@inputText(
field = helloForm("repeat"),
args = '_label -> "How many times?", 'size -> 3, 'placeholder -> 10
)
}
渲染界面需要在页面上开始标注所需要传入页面的必要参数如: @(message:String)(name:String)(list:List[Any])(op:Option[Any])
从Action想页面中传递参数,根据页面指定的参数传递如: views.html.index("message:String")("name:String")(List[Any])(Option[Any])
页面中遍历参数 使用@ 可以使用for map等进行遍历