将Golang变量分配给Javascript。

huangapple go评论103阅读模式
英文:

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?

英文:

Currently I am having an issue related to assign a Golang variable to a Javascript variable. I am using the Golang templates, so, from the backend I sent a JSON variable, just like this:

 var c []models.C
 b, _ := json.Marshal(c)
 err = tpl.ExecuteTemplate(w, "index.gohtml",string(b))

As you see, I have a slice, convert it to Json and then that Json to string, and send it to the template. Then, in the frontend I need to assign that to a variable, and it should be valid JSON, I have this:

var rowData = {{.}};

But, I am getting SyntaxError: expected property name, got '{'

So, my question is: How should I assign that JSON?

答案1

得分: 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对象),并且已经正确转义。

英文:

First, you must use the html/template instead of text/template, as the former provides context-sensitive escaping.

Second, in the template the context must be clear that it is JavaScript code, e.g. it must be inside HTML &lt;script&gt; tag.

See this working example:

type Point struct {
	Name string
	X, Y int
}

func main() {
	t := template.Must(template.New(&quot;&quot;).Parse(src))

	p := Point{&quot;Center&quot;, 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 = `&lt;script&gt;
var point = {{.}};
alert(point);
&lt;/script&gt;`

Output (try it on the Go Playground):

&lt;script&gt;
var point = &quot;{\&quot;Name\&quot;:\&quot;Center\&quot;,\&quot;X\&quot;:100,\&quot;Y\&quot;:200}&quot;;
alert(point);
&lt;/script&gt;

As you can see, the point JavaScript variable contains a valid JSON text (a JavaScript Object), properly escaped.

答案2

得分: 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-file.go.html 文件中添加一个 script 标签,并在其中定义全局变量。稍后您可以在 JS 文件中访问这些变量。

<script type="text/javascript">
    // 注意 JSON.parse 和 json 函数!
    let event = JSON.parse({{ json .MyStruct }});
</script>

// 在下面,您可以像往常一样导入您的 JS 文件。
<script type="text/javascript" src="/assets/js/index.js"></script>
英文:

You can write custom template function that will marshal your struct into json. That way you don't have to marshal all your structs in the handler yourself. Especially if you need your struct in HTML template as well as in JS script.

Example using Gin.

In main.go file.

    router := gin.New()
	router.SetFuncMap(template.FuncMap{
		&quot;json&quot;: func(s interface{}) string {
			jsonBytes, err := json.Marshal(s)
			if err != nil {
				return &quot;&quot;
			}
			return string(jsonBytes)
		},
	})

In your handler function.

type MyStruct struct {
    Foo string `json:&quot;foo&quot;`
}

func Handler(ctx *gin.Context) {
    myStruct := MyStruct{
        Foo: &quot;test&quot;,
    }
    
    ctx.HTML(http.StatusOK, &quot;template-file.go.html&quot;, gin.H{
		&quot;MyStruct&quot;:   myStruct,
	})
}

Finally in your template.go.html file add a script tag and define here your global variables. Later on you can access them in your JS file.

&lt;script type=&quot;text/javascript&quot;&gt;
    // NB on JSON.parse and json functions!
    let event = JSON.parse({{ json .MyStruct }});
&lt;/script&gt;

// Below you can import your JS file as usual.
&lt;script type=&quot;text/javascript&quot; src=&quot;/assets/js/index.js&quot;&gt;&lt;/script&gt;

huangapple
  • 本文由 发表于 2017年8月3日 23:19:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/45488393.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定