【问题标题】:How to pass multiple data objects to HTML templates in Golang如何将多个数据对象传递给 Golang 中的 HTML 模板
【发布时间】:2017-06-17 22:56:48
【问题描述】:

我将表的所有行作为 json 格式返回到变量 pdata 并将其解组为接口对象。 我有一个用户结构的实例,我想将它与未编组的 json 数据一起传递给渲染函数,并使用 html 模板中的字段参数{{.fieldname}} 访问它。

if uuid != "" {
    pdata, err := getProduct()
    if err != nil {
        fmt.Println(err)
    } 

    type Prdata struct {
        Puid     string `json:"puid"`
        Pname    string `json:"pname"`
        Quantity string `json:"quantity"`
        Price    string `json:"price"`
        Image    string `json:"image"`
    }

    // Obj:= make(map[Prdata]string)

    var Pr Prdata

    err = json.Unmarshal(pdata , &Pr)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(string(pdata))
    fmt.Println(Pr)
    fmt.Println(u)

    render(w, "internal", Pr)
}

fmt.Println(string(pdata)) 给出这个输出

[{"image":"1Appleiphone7.jpeg","pname":"iphone7","price":"70000","puid":"d6742e4e-2ad6-43c5-97f4-e8a7b00684e2","quantity" :"100"}]

我只是成功地将数据解组为interface{} 对象。尝试使用 interface{} 类型的键和 string 类型的值制作地图,但它会引发错误:

"json: 无法将数组解组为 map[interface {}]string 类型的 Go 值"

渲染函数接受interface{}类型的参数

func render(w http.ResponseWriter, name string, data interface{})

fmt.Println(Pr) 给出这个输出:

[地图[数量:100 图片:1Appleiphone7.jpeg pname:iphone7 价格:70000 puid:d6742e4e-2ad6-43c5-97f4-e8a7b00684e2]]

u 是结构体User 的一个实例

var u = &User{}

type User struct {
    Uuid     string            
    Username string           
    Password string           
    Fname    string            
    Email    string            
}

我可以使用管道{{.}} 在 html 页面上看到输出。但是我无法使用字段名访问任何数据。

一定有办法做到这一点。但我不确定如何?

当我传递以下类型的 json 时,我可以将其传递给结构类型并使用模板中的管道通过键值引用它。

    str := `{
    "image": "1Appleiphone7.jpeg",
    "pname": "iphone7",
    "price": "70000",
    "puid": "d6742e4e-2ad6-43c5-97f4-e8a7b00684e2",
    "quantity": "100"
    }`

解组函数

err = json.Unmarshal([]byte(str), &Pr)

DB记录pdata和上面str的json数据的区别在于使用了反引号“`”。看起来虽然json数据显示的是键值对,但它实际上是一个json数组,而不是一个json对象。有没有办法解决这个问题?

【问题讨论】:

  • 试试 map[string]interface{}
  • 您的问题是关于解组(据我所知)而不是关于模板。请将主题更改为:“Unmarshal multi-item json with GoLang”。

标签: parsing templates go interface


【解决方案1】:

您不需要 map[interface{}]string 来解组 json obj。您的 json 相当于地图切片:

[
    {
        "image":"1Appleiphone7.jpeg",
        "pname":"iphone7",
        "price":"70000",
        "puid":"d6742e4e-2ad6-43c5-97f4-e8a7b00684e2",
        "quantity":"100"
    }
]

要解组的对象应该是带有字符串键和值的映射切片:

var Pr []map[string]string

Playground

顺便说一句,我相信那里隐藏着误解:

渲染函数采用接口类型的参数{}

我的意思不是你必须在那里传递一个interface{} 类型的变量,而是意味着你可以将一个任何类型的变量传递给render 函数。

【讨论】:

  • 也许我需要做的是创建一个包含产品结构字段的结构,另一个结构说数据包含用户和产品类型。我需要将 json 解组到产品结构中并将数据传递给渲染函数。我一直在尝试,但无法做到正确
  • 您可以根据需要解组 jason obj,但我不知道什么是 Product 类型以及如何在我从未见过的代码中使用它。我只能认为您发布的 json obj 可以轻松解组为 []map[string]string。
【解决方案2】:

我正在发布一个将 json 作为字节解组为结构类型的工作示例,然后可以使用模板中的 {{.}} 来引用该结构类型。

主包

import (
    "encoding/json"
    "fmt"
)

type Usrdata struct {
    Uuid  string
    Fname string
}

type Prdata struct {
    Puid     string `json:"puid"`
    Pname    string `json:"pname"`
    Quantity string `json:"quantity"`
    Price    string `json:"price"`
    Image    string `json:"image"`
}

type Data struct {
    U Usrdata
    P []Prdata
}

func main() {
    Ur := Usrdata{Uuid: "xyz", Fname: "Somename"}
    Pr := make([]Prdata, 0)
    var Dt Data
    Dt.U = Ur
    pdata := `[{"image":"1Appleiphone7.jpeg","pname":"iphone7","price":"70000","puid":"d6742e4e-2ad6-43c5-97f4-e8a7b00684e2","quantity":"100"}]`
    err := json.Unmarshal([]byte(pdata), &Pr)
    if err != nil {
        fmt.Println(err)
    }
    Dt.P = Pr
    fmt.Println(Pr[0].Pname)
    fmt.Println(Pr)
    fmt.Println(Dt)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-15
    • 2016-06-03
    • 2022-11-14
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    相关资源
    最近更新 更多