如何将嵌套的结构体传递给 gohtml 模板文件,并在表格中显示它?

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

How can I pass a nested struct to a gohtml template file and display it in a table?

问题

我无法解决你的问题,但我可以为你提供一些帮助。根据你提供的代码和模板,我注意到可能有几个问题导致数据无法显示在表格中。

首先,请确保你的HTML模板文件正确引用了bootstrap.gohtml文件,并且正确定义了"yield"模板块。你可以检查一下这些文件的路径和文件名是否正确。

其次,你在模板中使用了.Items来迭代数据,但在你的Go代码中,你将数据存储在了data变量中,而不是data.Items。你可以尝试将data.Items传递给table.Render方法,看看是否能够正确显示数据。

另外,你可以在tableHandler函数中添加一些调试语句,以确保数据在传递给模板之前是正确的。例如,你可以使用fmt.Printlnspew.Dump来打印data变量的值,以确保它包含了你期望的数据。

最后,如果你的数据仍然无法显示在表格中,你可以检查一下浏览器的开发者工具,查看是否有任何错误或警告信息。这可能有助于确定问题所在。

希望这些提示对你有帮助!如果你有任何其他问题,请随时提问。

英文:

I can't figure out how to pass the data that I get from the MySQL database to my HTML template and display every column in a table.

The Instructions I found work fine, however when i try to implement it into my own code it won't pass the data to my HTML and the table remains empty.

Go code:


var table = NewView("bootstrap", "views/pages/table.gohtml")

func main() {
	http.Handle("/views/", http.StripPrefix("/views/", http.FileServer(http.Dir("./views"))))
	http.HandleFunc("/table", tableHandler)
	fmt.Println("server running on port :8080")
	http.ListenAndServe(":8080", nil)
}
func tableHandler(w http.ResponseWriter, r *http.Request) {
	db := ipSQL.SqlConnect()

	data := ipSQL.SqlSelect(db)
	// This returns a nested struct and stores it in the 'data' variable.
	/*
		type Data struct {
		Items []Devicevalue_view
		}

		type Devicevalue_view struct {
			Name        string
			Ip          string
			Pcn         string
			Description string
		}
	*/

	fmt.Println(data)
	//The println prints the following: 'test1: {[{Name1 192.168.166.13 123456 webserver} {Name2 192.168.166.14 123456 webserver2}]}'

	err := table.Render(w, data)
	//This renders the page together with a default layout. table is initialized somewhere else in this way:
	// var table = NewView("bootstrap", "views/pages/table.gohtml") --> This is a function I found and confirmed to be working.
	if err != nil {
		panic(err)
	}
}

I've been using the following code to render a standard layout for my webpage from a different file called bootstrap.gohtml and get the body of the HTML from the file I specify. (Added this in ---UPDATE 2)



func NewView(layout string, files ...string) *View {
	files = append(layoutFiles(), files...)
	t, err := template.ParseFiles(files...)
	if err != nil {
		panic(err)
	}

	return &View{
		Template: t,
		Layout:   layout,
	}
}

type View struct {
	Template *template.Template
	Layout   string
}

func (v *View) Render(w http.ResponseWriter, data interface{}) error {
    spew.Dump(data)
	return v.Template.ExecuteTemplate(w, v.Layout, data)
}

func layoutFiles() []string {
	files, err := filepath.Glob(LayoutDir + "/*.gohtml")
	if err != nil {
		panic(err)
	}
	return files
}


The HTLM template looks like this, note that table.Render uses bootstrap.gohtml in which i call on the 'yield' template which I define in table.gohtml.

{{define "yield"}}
<!DOCTYPE html>
<html lang="en">
    <body>
        <table >
            <tr>
                <th>name</th>
                <th>ip</th>
                <th>pcn</th>
                <th>description</th>
            </tr>
            {{ range .Items}}
            <tr>
                <td>{{ .Name }}</td>
                <td>{{ .Ip }}</td>
                <td>{{ .Pcn }}</td>
                <td>{{ .Description }}</td>
            </tr>
            {{ end}}
        <tr>
            <td>END</td>
        </tr>
    </table>
</body>
</html>
{{end}}

The bootstrap.gohtml looks something like this:

{{define "bootstrap"
   <head>some links to css among other things</head>
   <nav>a navigation bar</nav>
   {{template "yield"}}
   <foot>footer</foot>
{{end}}

I compared my code to a working example and the data needed for the table seems to be correct leaving me to believe the issue lies in getting the variables into the HTML table.

I've tried many other variable names in my html file but it won't add them to the table, the column names work fine just not the contents.

The result I expect is a table with multiple rows that has the data that I've currently stored in the 'data' variable.

---UPDATE 1
I've replaced '{{ range .}}' with '{{ range .Items}}' but it still wont show the data in the table.

---UPDATE 2
Added more of my code to the post.

---UPDATE 3
I've added spew.Dump(data) to the render() function, the output is the following:

server running on port :8080
{[{Name1 192.168.166.13 123456 Webserver1} {Name2 192.168.166.14 123456 Webserver2}]}
(ipSQL.Data) {
 Items: ([]ipSQL.Devicevalue_view) (len=2 cap=2) {
  (ipSQL.Devicevalue_view) {
   Name: (string) (len=5) "Name1",
   Ip: (string) (len=14) "192.168.166.13",
   Pcn: (string) (len=6) "123456",
   Description: (string) (len=10) "Webserver1"
  },
  (ipSQL.Devicevalue_view) {
   Name: (string) (len=5) "Name2",
   Ip: (string) (len=14) "192.168.166.14",
   Pcn: (string) (len=6) "123456",
   Description: (string) (len=10) "Webserver2"
  }
 }
}

答案1

得分: 0

我通过将{{template "yield"}}更改为{{template "yield" .}}使其正常工作。
据我所了解,这将使用管道将变量解析到下一个模板文件中。

{{define "bootstrap"}}
   <head>一些链接到CSS和其他内容</head>
   <nav>导航栏</nav>
   {{template "yield" .}}
   <foot>页脚</foot>
{{end}}

现在,yield模板可以访问我解析到bootstrap模板的变量。

英文:

I got it working by changing {{template "yield"}} to {{template "yield" .}}.
From what I understand of it this will used the pipeline to parse the variables to the next template file.

{{define &quot;bootstrap&quot;
   &lt;head&gt;some links to css among other things&lt;/head&gt;
   &lt;nav&gt;a navigation bar&lt;/nav&gt;
   {{template &quot;yield&quot; .}}
   &lt;foot&gt;footer&lt;/foot&gt;
{{end}}

The yield template now has access to the variables I parsed to the bootstrap template.

huangapple
  • 本文由 发表于 2022年4月13日 23:50:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/71860373.html
匿名

发表评论

匿名网友

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

确定