将Golang变量分配给Javascript

7

目前我遇到了一个相关的问题,就是将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?


2
我不确定你想要实现什么,但是这个 {{.}} 看起来不像是一个 JSON -> https://jsonlint.com/ - Edwin
1
请展示完整的例子。"SyntaxError: expected property name"不是Go语言错误。你的模板输出是什么?这是一个文本模板吗?为什么不直接使用fmt.Sprintf("var rowData = %s;", b) - JimB
1
@Edwin 使用{{.}}我可以在前端打印Golang变量。 {{.}}它不是值,而是访问变量的方式。 - Sredny M Casanova
1
@JimB 我同意,这是一个Javascript问题,因为我正尝试将Go变量(它是一个字符串但JSON有效)赋值给JS变量。 - Sredny M Casanova
@SrednyMCasanova 没有代码展示在哪里使用,很难确定这是在模板中使用还是模板的输出结果。 - Edwin
2个回答

10
首先,您必须使用html/template而不是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对象),已经进行了适当的转义。

1

您可以编写自定义模板函数,将您的结构体转换为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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接