Revel 盡可能讓客戶端傳來的參數轉換成Go語言的數據類型變得簡單。這種從字符串轉換成另外一種類型被稱為“數據綁定”。
## 參數
所有的請求參數被收集到一個單獨的?`Params`?對象中. 包括:
* URL 路徑參數
* URL 查詢參數
* 表單字段 (Multipart or not)
* 文件上傳
Params對象定義在 ([godoc](http://gorevel.cn/docs/docs/godoc/params.html))中:
~~~
type Params struct {
url.Values
Files map[string][]*multipart.FileHeader
}
~~~
嵌入的?`url.Values`?([godoc](http://www.golang.org/pkg/net/url/#Values)) 提供了簡單值的查詢支持, 但是開發者可以更方便的使用Revel的數據綁定支持,提取參數到任意的數據類型。
## 控制器方法參數綁定
參數可以直接綁定到控制器方法,例如:
~~~
func (c AppController) Action(name string, ids []int, user User, img []byte) revel.Result {
...
}
~~~
在控制器方法執行之前, Revel 通過變量名稱綁定器解析參數到指定的數據類型,如果解析參數失敗, 參數將被解析到目標數據類型的初始值。
## 綁定器
使用 Revel 的綁定器綁定一個參數到指定的數據類型 ([godoc](http://gorevel.cn/docs/docs/godoc/binder.html)),它集成了Params對象。例如:
~~~
func (c SomeController) Action() revel.Result {
var ids []int
c.Params.Bind(&ids, "ids")
...
}
~~~
支持的數據類型有:
* Int
* Bool
* Point
* Slice
* Struct
* time.Time
* 文件上傳:*os.File, []byte, io.Reader, io.ReadSeeker
數據類型綁定的語法描述如下,詳細內容描述也可以參考?[源代碼](http://gorevel.cn/docs/docs/src/binder.html)。
### Booleans
字符串 “true”, “on”, 和 “1” 被綁定到?**true**,其他的為?**false**.
### Slices
切片綁定有兩種語法:有序和無序
有序:
~~~
?ids[0]=1
&ids[1]=2
&ids[3]=4
~~~
綁定結果為?`[]int{1, 2, 0, 4}`
無序:
~~~
?ids[]=1
&ids[]=2
&ids[]=3
~~~
綁定結果為?`[]int{1, 2, 3}`
**注意:**?只有有序切片可以綁定到一個 []Struct:
~~~
?user[0].Id=1
&user[0].Name=rob
&user[1].Id=2
&user[1].Name=jenny
~~~
### Struct
Struct簡單的使用一個 . 進行綁定:
~~~
?user.Id=1
&user.Name=rob
&user.Friends[]=2
&user.Friends[]=3
&user.Father.Id=5
&user.Father.Name=Hermes
~~~
綁定到下面的struct類型:
~~~
type User struct {
Id int
Name string
Friends []int
Father User
}
~~~
**注意:**?struct中的字段必須是導出的(首字母大寫)。
### Date / Time
內置的 SQL 標準時間格式 [“2006-01-02”, “2006-01-02 15:04”]
使用?[Revel官方模式](http://golang.org/pkg/time/#pkg-constants)?簡單的添加時間格式到?`TimeFormats`?變量:
~~~
func init() {
revel.TimeFormats = append(revel.TimeFormats, "01/02/2006")
}
~~~
### 文件上傳
文件上傳參數可以綁定到以下幾種類型:
* *os.File
* []byte
* io.Reader
* io.ReadSeeker
它是?[Go的 multipart 包](http://golang.org/pkg/mime/multipart/)?的一個包裝器. 文件保存在內存中,如果文件大小超過10MB(默認值), 就會被保存到一個臨時文件中。
**注意:**?綁定?`os.File`類型,會保存到臨時文件 (如果沒有的話),所以效率低。
### 自定義綁定器
應用程序可以定義綁定器。
自定義綁定器需要實現?[binder](http://gorevel.cn/docs/docs/godoc/binder.html#Binder)?接口并注冊自定義類型:
~~~
var myBinder = revel.Binder{
Bind: func(params *revel.Params, name string, typ reflect.Type) reflect.Value {...},
Unbind: func(output map[string]string, name string, val interface{}) {...},
}
func init() {
revel.TypeBinders[reflect.TypeOf(MyType{})] = myBinder
~~~