Golang如何将JSON数据嵌入HTML模板?
Golang如何将JSON数据嵌入HTML模板?
我尝试将菜单存储在数据库中,并用它来填充Go HTML模板。我已经成功获取了JSON数据并独立完成了Go HTML模板的填充。但是,如何将JSON数据从 func main 传递到模板函数 func page 中呢?
package main
import (
"encoding/json"
"fmt"
"html/template"
"io/ioutil"
"net/http"
"os"
)
func main() {
resp, err := http.Get("https://api3.go4webdev.org/menu/all")
if err != nil {
fmt.Println("No response")
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(body)) // 如何将此传递给 "func page" 并填充菜单?
page()
}
func page() {
fmt.Println()
t := template.Must(template.New("").Parse(templ))
m := map[string]interface{}{}
if err := json.Unmarshal([]byte(jsondata), &m); err != nil {
panic(err)
}
if err := t.Execute(os.Stdout, m); err != nil {
panic(err)
}
}
const templ = `
<html><body>
<ul>
<li id={{.menu_id}}>{{.menu_txt}}</li>
<li id={{.menu_id}}>{{.menu_txt}}</li>
</ul>
</body></html>`
const jsondata = `{"menu_id":"1", "menu_txt": "Home"}`
结果将是这样的:
[{"menu_icn":"","menu_id":"code","menu_lnk":"/code","menu_main":"code","menu_sort":1,"menu_txt":"Code Philosophy"},{"menu_icn":"","menu_id":"home","menu_lnk":"/home","menu_main":"home","menu_sort":1,"menu_txt":"Navigation”}, etc…]
<html><body>
<ul>
<li id=1>Home</li>
<li id=1>Home</li>
</ul>
</body>
当我尝试将JSON数据传递到 func page(jsondata) 时…
...
page(string(body))
}
func page(jsondata) {
....
…我遇到了一些错误
./main.go:23:11: undefined: jsondata ./main.go:28:34: undefined: jsondata
如果我在jsondata后面加上string
page(string(body))
}
func page(jsondata string) {
我得到了这些错误:
cannot unmarshal array into Go value of type map[string]interface {}
更多关于Golang如何将JSON数据嵌入HTML模板?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
是的,[]map[string]interface{} 比 []interface{} 更具体一些,这应该会使访问数据的代码更简单。
func main() {
fmt.Println("hello world")
}
无法将数组反序列化为 Go 类型 map[string]interface {}
你可以将 JSON 数组反序列化为 Go 的 []interface{},或者将 JSON 对象反序列化为 Go 的 map[string]interface{}。更好的做法是使用与你的 JSON 结构模式匹配的更具体的 Go 类型。
你需要对JSON的结构有一定的理解。
我确实理解JSON的结构。但在Go中读写JSON的语义和语法让我感到困惑。
举个例子,这让我很困惑:
m := []map[string]interface{}
// 这行不通 但是
var m []map[string]interface{}
// 这行得通
你可以将JSON数组解组到Go的
[]interface{}中,或者将JSON对象解组到Go的map[string]interface{}中。
m := map[string]interface{}{}
if err := json.Unmarshal([]interface(jsondata), &m); err != nil {
panic(err)
}
语法错误:意外的 (,期望的是 {
或者你的意思是?
m := []map[string]interface{} 为变量 m 分配了一个类型,因为右侧是一个 map 切片类型,而不是一个值。
var m []map[string]interface{} 声明变量 m 为某个类型(map 切片类型)。它会被隐式初始化为该类型的零值。
:= 是声明并初始化变量的简写形式。变量的值将被设置为右侧的值,其类型将从右侧的类型推断出来。Go 语言之旅
在使用 json.Unmarshal 时,无需初始化变量,因为 Unmarshal 会设置变量的值。
你好 Sibert,
你能将请求体作为 []byte 发送吗?
这样你就不需要将数据转换两次了。
package main
import (
"encoding/json"
"fmt"
"html/template"
"io"
"net/http"
"os"
)
func main() {
resp, err := http.Get("https://api3.go4webdev.org/menu/all")
if err != nil {
fmt.Println("No response")
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
fmt.Println(string(body)) // 如何将此传递给 "func page" 并填充菜单?
page(body)
}
func page(jsondata []byte) {
fmt.Println()
t := template.Must(template.New("").Parse(templ))
m := map[string]interface{}{}
if err := json.Unmarshal([]byte(jsondata), &m); err != nil {
panic(err)
}
if err := t.Execute(os.Stdout, m); err != nil {
panic(err)
}
}
const templ = `
<html><body>
<ul>
<li id={{.menu_id}}>{{.menu_txt}}</li>
<li id={{.menu_id}}>{{.menu_txt}}</li>
</ul>
</body></html>`
你能将请求体以
[]byte的形式发送吗?
你的代码给出了这个错误:
panic: json: cannot unmarshal array into Go value of type map[string]interface {}
JSON 在我的 API 和外部 API 中都是一个非常通用的标准。所以我想我必须学习如何处理 JSON。我该如何对数据进行两次转换?
这里有一个不涉及 API 的示例。错误和之前一样:
package main
import (
"encoding/json"
"html/template"
"os"
)
func main() {
t := template.Must(template.New("").Parse(templ))
m := map[string]interface{}{}
if err := json.Unmarshal([]byte(jsondata), &m); err != nil {
panic(err)
}
if err := t.Execute(os.Stdout, m); err != nil {
panic(err)
}
}
const templ = `
<html><body>
{{ range . }}
<li id={{.menu_id}}> {{ .menu_txt }}</li>
{{ end }}
</body></html>`
const jsondata = `[{"menu_id":"1", "menu_txt": "Home"},{"menu_id":"2", "menu_txt": "Prefs"}]`
panic: json: cannot unmarshal array into Go value of type map[string]interface {}
在Go中传递JSON数据到模板函数时,需要正确处理函数参数和JSON结构。以下是修改后的代码:
package main
import (
"encoding/json"
"fmt"
"html/template"
"io/ioutil"
"net/http"
"os"
)
func main() {
resp, err := http.Get("https://api3.go4webdev.org/menu/all")
if err != nil {
fmt.Println("No response")
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
// 传递JSON数据到page函数
page(string(body))
}
func page(jsondata string) {
t := template.Must(template.New("").Parse(templ))
// 根据JSON结构选择正确的解析方式
var data []map[string]interface{}
if err := json.Unmarshal([]byte(jsondata), &data); err != nil {
panic(err)
}
// 传递数据到模板
if err := t.Execute(os.Stdout, data); err != nil {
panic(err)
}
}
const templ = `
<html><body>
<ul>
{{range .}}
<li id="{{.menu_id}}">{{.menu_txt}}</li>
{{end}}
</ul>
</body></html>`
如果JSON是单个对象而不是数组,使用以下模板:
const templ = `
<html><body>
<ul>
<li id="{{.menu_id}}">{{.menu_txt}}</li>
</ul>
</body></html>`
对应的page函数修改:
func page(jsondata string) {
t := template.Must(template.New("").Parse(templ))
var data map[string]interface{}
if err := json.Unmarshal([]byte(jsondata), &data); err != nil {
panic(err)
}
if err := t.Execute(os.Stdout, data); err != nil {
panic(err)
}
}
对于更复杂的模板处理,可以使用自定义结构体:
type MenuItem struct {
MenuID string `json:"menu_id"`
MenuTxt string `json:"menu_txt"`
MenuLnk string `json:"menu_lnk"`
MenuIcn string `json:"menu_icn"`
MenuMain string `json:"menu_main"`
MenuSort int `json:"menu_sort"`
}
func page(jsondata string) {
t := template.Must(template.New("").Parse(templ))
var menuItems []MenuItem
if err := json.Unmarshal([]byte(jsondata), &menuItems); err != nil {
panic(err)
}
if err := t.Execute(os.Stdout, menuItems); err != nil {
panic(err)
}
}
const templ = `
<html><body>
<ul>
{{range .}}
<li id="{{.MenuID}}">
<a href="{{.MenuLnk}}">{{.MenuTxt}}</a>
</li>
{{end}}
</ul>
</body></html>`



