当前位置: 首页 > news >正文

goweb项目结构以及如何实现前后端交互

项目结构

在这里插入图片描述

HTML模板

使用ParseFiles可以解析多个模板文件

func ParseFiles(filenames ...string)(*Teplate,error){return parseFiles(nil,filenames...)
}

把模板信息响应写入到输入流中

func (t *Template) Exwcute(wr io.Writer,data interface{})error{if err:=t.escape();err!=nil{return err}return t.text.Execute(wr,data)
}

在这里插入图片描述

index.js

function myclick(){alert("您点击了按钮")
}

index.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><script type="text/javascript" src="/demo/static/js/index.js"></script>
</head>
<body>
html
<button onclick="myclick()">按钮</button>
</body>
</html>

main.go

package mainimport ("html/template""net/http"
)func welcome(w http.ResponseWriter, r *http.Request) {t, _ := template.ParseFiles("demo/view/index.html")t.Execute(w, nil)
}func main() {server := http.Server{Addr: ":8090"}//当发现url以/static开头把请求转发给指定的路径http.Handle("/demo/static/", http.StripPrefix("/demo/static/", http.FileServer(http.Dir("demo/static"))))http.HandleFunc("/", welcome)server.ListenAndServe()
}

向模板传递数据

可以在HTML中使用{f}获取template.Execute()第二个参数传递的值

最常用的 {{.}} 中的""是指针,指向当前变量,称为"dot”

在{{}}可以有的Argument,官方给定如下

在这里插入图片描述

向HTML传递字符串数据,在HTML中使用((.})获取传递数据即可,所有基本类型都是使用此方式进行传递

传递普通值类型

main.go

package mainimport ("html/template""net/http"
)func welcome(w http.ResponseWriter, r *http.Request) {t, _ := template.ParseFiles("demo/view/index.html")t.Execute(w, "smallming")}func main() {server := http.Server{Addr: ":8090"}http.HandleFunc("/", welcome)server.ListenAndServe()
}

index.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><script type="text/javascript" src="/demo/static/js/index.js"></script>
</head>
<body>
{{.}}
</body>
</html>

运行后在浏览器显示smallming

传递结构体类型数据

index.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><script type="text/javascript" src="/demo/static/js/index.js"></script>
</head>
<body>
获取到的数据:
姓名 {{.Name}}<br/>
年龄 {{.Age}}
</body>
</html>

main.go

package mainimport ("html/template""net/http"
)type User struct {Name stringAge  int
}func welcome(w http.ResponseWriter, r *http.Request) {t, _ := template.ParseFiles("demo/view/index.html")t.Execute(w, User{"zhang", 18})}func main() {server := http.Server{Addr: ":8090"}http.HandleFunc("/", welcome)server.ListenAndServe()
}

传递Map数据

main.go

package mainimport ("html/template""net/http"
)type User struct {Name stringAge  int
}func welcome(w http.ResponseWriter, r *http.Request) {t, _ := template.ParseFiles("demo/view/index.html")m := make(map[string]interface{})m["user"] = User{"zhang", 18}m["money"] = 88888888888t.Execute(w, m)}func main() {server := http.Server{Addr: ":8090"}http.HandleFunc("/", welcome)server.ListenAndServe()
}

index.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><script type="text/javascript" src="/demo/static/js/index.js"></script>
</head>
<body>
获取到的数据:
姓名 {{.user.Name}}<br/>
年龄 {{.user.Age}}<br/>
财富 {{.money}}
</body>
</html>

在模板中调用函数

在模版中调用函数时,如果是无参函数直接调用函数名即可,没有函数的括号

例如在go源码中 时间变量,year()在模版中 {{时间.Year}}

在模版中调用有参函数时参数和函数名称之间有空格,参数和参数之间也是空格

给定go文件代码

调用给定的方法

mian.go

package mainimport ("html/template""net/http""time"
)type User struct {Name stringAge  int
}func welcome(w http.ResponseWriter, r *http.Request) {t, _ := template.ParseFiles("demo/view/index.html")time := time.Date(2004, 3, 3, 5, 7, 3, 2, time.Local)t.Execute(w, time)}func main() {server := http.Server{Addr: ":8090"}http.HandleFunc("/", welcome)server.ListenAndServe()
}

index.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><script type="text/javascript" src="/demo/static/js/index.js"></script>
</head>
<body>
获取到的数据:
完整时间 {{.}}<br/>{{.Year}}<br/>{{.Month}}<br/>
转换后的格式
{{.Format "2006-01-02 15:04:03"}}
</body>
</html>

调用自定义方法

如果希望调用自定义函数,需要借助html/template包下的FuncMap进行映射

FuncMap本质就是map的别名 type FuncMap map[string]interface{}

函数被添加映射后,只能通过函数在FuncMap中的key调用函数

main.go

package mainimport ("html/template""net/http""time"
)type User struct {Name stringAge  int
}func MyTransfer(t time.Time) string {return t.Format("2006-03-05 15:02:04")
}func welcome(w http.ResponseWriter, r *http.Request) {//把自定义函数绑定在funcMap上fm := template.FuncMap{"mt": MyTransfer}t := template.New("index.html").Funcs(fm)t, _ = t.ParseFiles("demo/view/index.html")time1 := time.Date(2018, 1, 2, 3, 4, 5, 0, time.Local)t.Execute(w, time1)}func main() {server := http.Server{Addr: ":8090"}http.HandleFunc("/", welcome)server.ListenAndServe()
}

index.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><script type="text/javascript" src="/demo/static/js/index.js"></script>
</head>
<body>
获取到的数据:
完整时间 {{.}}<br/>{{.Year}}<br/>{{.Month}}<br/>
转换后的格式<br/>
{{.Format "2006-01-02 15:04:03"}}<br/>
调用自定义函数<br/>
{{mt .}}
</body>
</html>

action

Go语言官方文档给出action(动作)的列表。"Arguments"和"pipelines"代表数据的执行结果

  • {{/*a comment */}}

    注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止,就像这里表示的一样。

  • {{pipeline}}
    pipeline的值的默认文本表示会被拷贝到输出里

  • {fif pipeline}} T1 {{end}}

    如果pipeline的值为empty,不产生输出,否则输出T1执行结果。不改变dot的值

    Empty值包括false、0、任意nil指针或者ni1接口,任意长度为8的数组、切片、字典。

  • {{if pipeline}} T1 {{else}} To {{end}}

  • 如果pipeline的值为empty,输出T执行结果,否则输出T1执行结果。不改变dot的值

  • {{if pipeline}} T1 {{else if pipeline}} re {{end}}

    用于简化if-else链条,else action可以直接包含另一个if;等价于:

    {{if pipeline}} T1 {{else}}{{if pipeline}} To {{end}}{{end}}

  • {{range pipeline}} T1{{end}}

    pipeline的值必须是数组、切片、字典或者通道

    如果pipeline的值其长度为0,不会有任何输出;

    否则dot依次设为数组、切片、字典或者通道的每一个成员元素并执行T1;

    如果pipeline的值为字典,且键可排序的基本类型,元素也会按键的顺序排序。

  • {{range pipeline}} T1 {felse}} To {fend}}

    pipeline的值必须是数组、切片、字典或者通道,

    如果pipeline的值其长度为8,不改变dot的值并执行T0;否则会修改dot并执行T1。

  • {template “name”}}

    执行名为name的模板,提供给模板的参数为ni1,如模板不存在输出为""

  • {{template “name” pipeline}}

    执行名为name的模板,提供给模板的参数为pipeline的值。

  • {{with pipeline}} T1{fend}}

    如果pipeline为empty不产生输出,否则将dot设为pipeline的值并执行T1。不修改外面的dot

  • {{with pipeline}} Tl {{else}} To {{end}}

    如果pipeline为empty,不改变dot并执行T0,否则dot设为pipeline的值并执行T1。

action主要完成流程控制、循环、模版等操作,通过使用action可以在模版中完成简单逻辑处理(复杂逻辑处理
应该在go中实现,传递给模版的数据应该是已经加工完的数据)

if使用

if写在模版中和写在go文件中功能是相同的,区别是语法

布尔函数会将任何类型的零值视为假,其余视为真。

if后面的表达式中如果包含逻辑控制符在模版中实际上是全局函数

在这里插入图片描述
在这里插入图片描述

main.go

package mainimport ("html/template""net/http"
)func welcome(w http.ResponseWriter, r *http.Request) {t, _ := template.ParseFiles("demo/view/index.html")t.Execute(w, "")}func main() {server := http.Server{Addr: ":8090"}http.HandleFunc("/", welcome)server.ListenAndServe()
}

index.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><script type="text/javascript" src="/demo/static/js/index.js"></script>
</head>
<body>
取出数据{{.}}<br/>
{{if .}}
执行了if
这相当于if{}内容
{{else}}
执行了else
{{end}}
html
</body>
</html>

if else if else的用法

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script type="text/javascript" src="/demo/static/js/index.js"></script>
</head>
<body>
{{$n:=123}}
{{if gt $n 456}}
执行if
{{else}}
执行else
{{end}}
</body>
</html>

range使用

main.go

package mainimport ("html/template""net/http"
)func welcome(w http.ResponseWriter, r *http.Request) {t, _ := template.ParseFiles("demo/view/index.html")arr := []string{"第一个", "第二个"}t.Execute(w, arr)}func main() {server := http.Server{Addr: ":8090"}http.HandleFunc("/", welcome)server.ListenAndServe()
}

index.go

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script type="text/javascript" src="/demo/static/js/index.js"></script>
</head>
<body>
{{range .}}
{{.}}<br/>
{{end}}
</body>
</html>

结果
在这里插入图片描述

如果是map的话直接取出map的value

模板嵌套

在实际项目中经常出现页面复用的情况,例如:整个网站的头部信息和底部信息复用可以使用动作{{template"模版名称"}}引用模版。引用的模版必须在HTML中定义这个模版

{{define“名称”}}
htm1
{{end}}

执行主模版时也要给主模版一个名称,执行时调用的是ExecuteTemplate()方法

main.go

package mainimport ("html/template""net/http"
)func welcome(w http.ResponseWriter, r *http.Request) {t, _ := template.ParseFiles("demo/view/index.html", "demo/view/head.html", "demo/view/foot.html")t.ExecuteTemplate(w, "layout", nil)
}func main() {server := http.Server{Addr: ":8090"}http.HandleFunc("/", welcome)server.ListenAndServe()
}

index.html

{{define "layout"}}
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Document</title>
</head>
<body>
{{template "head" "传递head过去的内容"}}<br/>
中间内容<br/>
{{template "foot" "传递foot过去的内容"}}<br/>
</body>
</html>
{{end}}

head.html

{{define "head"}}
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Document</title>
</head>
<body>
head {{.}}
</body>
</html>
{{end}}

foot.html

{{define "foot"}}
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Document</title>
</head>
<body>
foot {{.}}
</body>
</html>
{{end}}

运行结果
在这里插入图片描述

相关文章:

  • 【GoChat】密码处理与实现JWT+进行功能单测
  • MuJoCo 关节角速度记录与可视化,监控机械臂运动状态
  • 【特殊场景应对9】视频简历的适用场景与风险分析
  • 测试模板x
  • AI 与高性能计算的深度融合:开启科技新纪元
  • 【互联网架构解析】从物理层到应用层的全栈组成
  • 前端开发本地配置 HTTPS 全面详细教程
  • Java 自定义TCP协议:【特点编码字符串<=>字节<=>特点编码16进制】16进制字符串和编码的转换 (各种编码通过字节向16进制的互转)| XOR计算
  • 在华为云平台上使用 MQTT 协议:构建高效可靠的物联网通信
  • crossOriginLoading使用说明
  • gradle-缓存、依赖、初始化脚本、仓库配置目录详解
  • 【锂电池剩余寿命预测】GRU门控循环单元锂电池剩余寿命预测(Matlab完整源码)
  • 发布-订阅模式应用场景及示例说明
  • 桥接模式(Bridge Pattern)详解
  • Eigen矩阵操作类 (Map, Block, 视图类)
  • 系统设计(2)—Redis—消息队列—数据库—熔限降
  • babel核心知识点
  • 理想星环OS选择NuttX作为MCU侧OS的核心原因分析​
  • 在 Linux 上安装 PNPM 的教程
  • 20250426在ubuntu20.04.2系统上打包NanoPi NEO开发板的FriendlyCore系统刷机eMMC的固件
  • 上海质子重离子医院已收治8000例患者,基本覆盖国内常见恶性肿瘤
  • 新任浙江省委常委、组织部长杨荫凯到嘉兴南湖瞻仰红船
  • 同款瑞幸咖啡竟差了6元,开了会员仍比别人贵!客服回应
  • 特朗普说克里米亚将留在俄罗斯,泽连斯基:绝不承认
  • 刘非任中共浙江省委常委、杭州市委书记
  • 体坛联播|卡马文加预计伤缺三个月,阿尔卡拉斯因伤退赛