将 Golang 变量分配给 Javascript
Assign Golang variable to Javascript
目前我遇到了将 Golang 变量分配给 Javascript 变量的相关问题。我使用的是 Golang 模板,所以,我从后端发送了一个 JSON 变量,就像这样:
var c []models.C
b, _ := json.Marshal(c)
err = tpl.ExecuteTemplate(w, "index.gohtml",string(b))
如您所见,我有一个切片,将其转换为 Json,然后将 Json 转换为字符串,并将其发送到模板。然后,在前端我需要将它分配给一个变量,它应该是有效的 JSON,我有这个:
var rowData = {{.}};
但是,我得到 SyntaxError: expected property name, got '{'
所以,我的问题是:我应该如何分配 JSON?
首先,你必须使用html/template
instead of text/template
,因为前者提供了上下文相关的转义。
其次,模板中的上下文必须清楚表明它是 JavaScript 代码,例如它必须在 HTML <script>
标签内。
查看这个工作示例:
type Point struct {
Name string
X, Y int
}
func main() {
t := template.Must(template.New("").Parse(src))
p := Point{"Center", 100, 200}
pj, err := json.Marshal(p)
if err != nil {
panic(err)
}
if err = t.Execute(os.Stdout, string(pj)); err != nil {
panic(err)
}
}
const src = `<script>
var point = {{.}};
alert(point);
</script>`
输出(在 Go Playground 上尝试):
<script>
var point = "{\"Name\":\"Center\",\"X\":100,\"Y\":200}";
alert(point);
</script>
如您所见,point
JavaScript 变量包含一个有效的 JSON 文本(一个 JavaScript 对象),已正确转义。
您可以编写自定义模板函数,将您的结构编组到 json。这样您就不必自己在处理程序中编组所有结构。特别是如果您需要在 HTML 模板和 JS 脚本中使用您的结构。
使用 Gin 的示例。
在 main.go 文件中。
router := gin.New()
router.SetFuncMap(template.FuncMap{
"json": func(s interface{}) string {
jsonBytes, err := json.Marshal(s)
if err != nil {
return ""
}
return string(jsonBytes)
},
})
在你的处理函数中。
type MyStruct struct {
Foo string `json:"foo"`
}
func Handler(ctx *gin.Context) {
myStruct := MyStruct{
Foo: "test",
}
ctx.HTML(http.StatusOK, "template-file.go.html", gin.H{
"MyStruct": myStruct,
})
}
最后在您的 template.go.html 文件中添加一个脚本标签并在此处定义您的全局变量。稍后您可以在您的 JS 文件中访问它们。
<script type="text/javascript">
// NB on JSON.parse and json functions!
let event = JSON.parse({{ json .MyStruct }});
</script>
// Below you can import your JS file as usual.
<script type="text/javascript" src="/assets/js/index.js"></script>
目前我遇到了将 Golang 变量分配给 Javascript 变量的相关问题。我使用的是 Golang 模板,所以,我从后端发送了一个 JSON 变量,就像这样:
var c []models.C
b, _ := json.Marshal(c)
err = tpl.ExecuteTemplate(w, "index.gohtml",string(b))
如您所见,我有一个切片,将其转换为 Json,然后将 Json 转换为字符串,并将其发送到模板。然后,在前端我需要将它分配给一个变量,它应该是有效的 JSON,我有这个:
var rowData = {{.}};
但是,我得到 SyntaxError: expected property name, got '{'
所以,我的问题是:我应该如何分配 JSON?
首先,你必须使用html/template
instead of text/template
,因为前者提供了上下文相关的转义。
其次,模板中的上下文必须清楚表明它是 JavaScript 代码,例如它必须在 HTML <script>
标签内。
查看这个工作示例:
type Point struct {
Name string
X, Y int
}
func main() {
t := template.Must(template.New("").Parse(src))
p := Point{"Center", 100, 200}
pj, err := json.Marshal(p)
if err != nil {
panic(err)
}
if err = t.Execute(os.Stdout, string(pj)); err != nil {
panic(err)
}
}
const src = `<script>
var point = {{.}};
alert(point);
</script>`
输出(在 Go Playground 上尝试):
<script>
var point = "{\"Name\":\"Center\",\"X\":100,\"Y\":200}";
alert(point);
</script>
如您所见,point
JavaScript 变量包含一个有效的 JSON 文本(一个 JavaScript 对象),已正确转义。
您可以编写自定义模板函数,将您的结构编组到 json。这样您就不必自己在处理程序中编组所有结构。特别是如果您需要在 HTML 模板和 JS 脚本中使用您的结构。
使用 Gin 的示例。
在 main.go 文件中。
router := gin.New()
router.SetFuncMap(template.FuncMap{
"json": func(s interface{}) string {
jsonBytes, err := json.Marshal(s)
if err != nil {
return ""
}
return string(jsonBytes)
},
})
在你的处理函数中。
type MyStruct struct {
Foo string `json:"foo"`
}
func Handler(ctx *gin.Context) {
myStruct := MyStruct{
Foo: "test",
}
ctx.HTML(http.StatusOK, "template-file.go.html", gin.H{
"MyStruct": myStruct,
})
}
最后在您的 template.go.html 文件中添加一个脚本标签并在此处定义您的全局变量。稍后您可以在您的 JS 文件中访问它们。
<script type="text/javascript">
// NB on JSON.parse and json functions!
let event = JSON.parse({{ json .MyStruct }});
</script>
// Below you can import your JS file as usual.
<script type="text/javascript" src="/assets/js/index.js"></script>