少女祈祷中...

本篇内容主要是对上一篇的补充。

自定义模板函数

在上一篇文章中,定义了这样一段函数。

1
2
3
4
func UnixToTime(timestamp int) string {
t := time.Unix(int64(timestamp), 0)
return t.Format("2006-01-02 15:04:05")
}

这就是一段自定义模板函数,其作用是接收一个参数timestamp,将时间戳转换成标准的时间格式并返回。它的调用是在default/index中。{{UnixToTime .date}},意思是后台向前台返回了一个时间戳date,让后通过自定义的UnixTotime函数对其进行标准化。

date是在defautlController.go中被返回的,在前台的html中要渲染它的话需要用{{.date}}调用。gin.H{}包含的内容就是所有从后台传给前台的数据,格式仿照下面的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
func (con DefaultController) Index(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "default/index.html", gin.H{
"title": "首页",
"msg": "我是msg",
"score": 89,
"hobby": []string{"吃饭", "睡觉", "写代码"},
"newsList": []interface{}{
Article{
Title: "新闻标题1",
Content: "新闻内容1",
},
Article{
Title: "新闻标题2",
Content: "新闻内容2",
},
},
"testSlice": []string{},
"news": Article{
Title: "新闻标题3",
Content: "新闻内容3",
},
"date": 1707723555,
})
}

另外就是关于t.Format("2006-01-02 15:04:05"),使用Format可以指定的时间的格式,并且只能用这个时间(2006-01-02 15:04:05),换成其他的时间不行。一般来说常用的是这些

  • 2006-01-02 15:04:05
  • Mon Jan 2 15:04:05 MST 2006
  • 01/02 03:04:05PM ‘06 -0700
    更多的还可以参考官方文档

从前台获取表单数据

想获取表单数据那就要先创造一个表单。
在templates/default下创建user.html。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{{define "default/user.html"}}

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="/static/css/base.css">
</head>
<body>
<!-- 注意这里的action的值doAddUser要与下文一样 -->
<form action="doAddUser" method="post">
<!-- 下面两个输入框的name指定的将要把数据传给后台哪个变量 -->
用户名:<input type="text" name="username">
<br>
<br>
密码:<input type="password" name="password">
<br>
<br>
<input type="submit" value="提交">
</form>
</body>
</html>

{{end}}

在controllers/defaults/defaultCoutroller.go中添加下面的函数。为了验证后台确实接受到了数据,这里在控制台打印的数据,并且在前台以json的格式返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 定义了一个结构体并把前台返回的数据绑定在结构体中。
type UserInfo struct {
Username string `json:"username" form:"username"` //form是浏览器链接?username=xxxx
Password string `json:"password" form:"password"` //这表示分别接收前台name="username"和name="password"的输入框提交的数据。
}
func (con DefaultController) DoAddUser(ctx *gin.Context) {
//这种方法可以不绑定结构体,直接获取前台数据,括号里的是html里的form里的input的name。
// username := ctx.PostForm("username")
// password := ctx.PostForm("password")

// 这里是绑定结构体的方法。
user := UserInfo{}
if err := ctx.ShouldBind(&user); err == nil {
fmt.Printf("user: %v\n", user)
ctx.JSON(http.StatusOK, gin.H{
"username": user.Username, //""里的是返回值,:后的是变量
"password": user.Password,
})
} else {
ctx.JSON(http.StatusOK, gin.H{
"err": err.Error(),
})
}
}

在routers/defaultRouters.go中配置路由。

1
2
3
4
5
6
7
8
9
10
11
12
func DefaultRoutersInit(r *gin.Engine) {
defaultRouters := r.Group("/")
{
defaultRouters.GET("/", defaults.DefaultController{}.Index)
defaultRouters.GET("/news", defaults.DefaultController{}.News)
defaultRouters.GET("/user", defaults.DefaultController{}.User)

//由于是向服务器发送数据,所以这里使用POST而不是GET。
//还要注意这里的"/doAddUser"路径要与前台的html中form的action值一样。
defaultRouters.POST("/doAddUser", defaults.DefaultController{}.DoAddUser)
}
}

从前台获取后台数据

这部分前面一直在用,也粗略地提及了一些。
这里以成分最复杂的templates/default/index.html为例。
{{template "public/page_header.html" .}}这段代码是调用了一个父模板,注意要在最后加上一个点。
{{$t := .title}}是获取从后台传过来的数据title并赋值给t。其中,$.都不能省略。

if语句

{{if ge .xxx yyy}}表示判断xxx >= yyyge也可以换成别的(这里真的没找到官方文档提供的示例,不过可以去知乎上找,有相关的语法)。
记得在用完if语句后加上{{end}}来结束语句。

循环遍历数据

在index.html中。
{{range $key,$value := .hobby}}
由于hobby是一个string类型的切片,所以这里的keyvalue就分别是下标和值。
也要记得在用完range循环以后加上一句{{end}}来结束循环。