从Golang结构体中返回JavaScript函数是可能的吗?

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

Is it posible to return javascript function from golang struct?

问题

下面是一个Go语言结构体的示例:

type Column struct {
    Data    string            `json:"data"`
    Title   string            `json:"title"`
    Type    string            `json:"type"`
    Class   string            `json:"class"`
    Visible bool              `json:"visible"`
    Render  template.JS       `json:"render"`
}

func (c *Column) SetValue() {
    // 根据条件,下面的代码可以灵活调整,但这里我保持简单。
    c.Render = template.JS(`function(data, type, row) { if(type === 'display'){ return $.fn.dataTable.render.text().display(data);} return data;}`);
}

这是Go语言模板中的JavaScript代码:

<script>
    $(function () {
        console.log({{.Columns}}, wantedobj);
    });
</script>

在Chrome开发者工具中,左侧列表是从上述结构体格式化的值,右侧列表是我想要的格式。

render中,是否有可能获取JavaScript函数而不是字符串?(请参考右侧图片中的render

英文:

Example below is a golang struct

type Column struct {
        Data            string      `json:&quot;data&quot;`
        Title           string      `json:&quot;title&quot;`
	    Type            string      `json:&quot;type&quot;`
	    Class           string      `json:&quot;class&quot;`
	    Visible         bool        `json:&quot;visible&quot;`
	    Render          template.JS `json:&quot;render&quot;`
}

func (c *Column) SetValue() {
        // code below is flexible depend on condition but here i keep it simple.
        c.Render = template.JS(`function(data, type, row) { if(type === &#39;display&#39;){ return $.fn.dataTable.render.text().display(data);} return data;}`);
}

Here is Javascript in golang template

&lt;script&gt;
    $(function () {
        console.log({{.Columns}}, wantedobj);
    });
&lt;/script&gt;

Here is chrome developer tools.

  • left list is format value from struct above.
  • right list is format that I want.

从Golang结构体中返回JavaScript函数是可能的吗?

on render is there any posible way to get javascript function instead of string? (please see render at right picture)

答案1

得分: 2

使用template.JS是正确的。你的问题在于,在HTML模板中,值是根据上下文进行转义的:

在解析时,每个{{.}}都被覆盖,根据需要添加转义函数。

<script>标签内,像{{.Columns}}这样的结构值会被渲染为JSON。现在,由于template.JS只是string的定义类型,当你将Columns作为JSON进行编组时,字段Render保持其字符串表示。

如果你直接打印Render,它将显示为未引用的Javascript:

console.log({{.Columns.Render}}); // 未转义的JS函数

现在你可能会考虑在Columns上实现MarshalJSON,将Render渲染为未转义的Javascript,但那将不再是有效的JSON。函数不是JSON数据类型。它只能是一个字符串。一个选项是改用text/template包,但它将不再转义任何内容。或者使用单个字段构建Javascript对象:

<script>
    $(function () {
        const foo = {
            data: {{.Columns.Data}},
            render: {{.Columns.Render}}
        }
        console.log(foo);
    });
</script>
英文:

Using template.JS is correct. Your problem is that in HTML templates, values are escaped based on contexts:

> At parse time each {{.}} is overwritten to add escaping functions as necessary.

Inside &lt;script&gt; tags, struct values such as {{.Columns}} are rendered as JSON. Now, since template.JS is simply a defined type over string, when you marshal Columns as JSON, the field Render keeps its string representation.

If you print Render directly, it will appear as unquoted Javascript:

console.log({{.Columns.Render}}); // unescaped JS function

Now you might think of implementing MarshalJSON on Columns to render Render as unescaped Javascript, but that wouldn't be valid JSON anymore. Function is not a JSON data type. It can only be a string. An option is to use text/template package instead, but it won't escape anything anymore. Or construct the Javascript object using the single fields:

&lt;script&gt;
    $(function () {
        const foo = {
            data: {{.Columns.Data}},
            render: {{.Columns.Render}}
        }
        console.log(foo);
    });
&lt;/script&gt;

huangapple
  • 本文由 发表于 2021年12月16日 04:50:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/70370140.html
匿名

发表评论

匿名网友

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

确定