Golang如何通过map接口填充HTML下拉菜单

Golang如何通过map接口填充HTML下拉菜单 大家好, 我正尝试在表单中集成一个选择框,但我已经有了一个可以遍历填充的map接口。我在网上看到了这个教程这里 但对我来说不合适的是使用常量变量存储所有HTML的方式,因为我试图分离页眉、页脚和内容… 是否有其他方法可以实现相同的结果? 感谢大家对我们这些新手的技术支持。

17 回复

非常感谢你的示例,我现在理解得更清楚了。

更多关于Golang如何通过map接口填充HTML下拉菜单的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


甚至要填充我的选择?

您可以将HTML代码放在单独的文件中(推荐做法),并使用html/template包通过Golang代码为其填充值。

你好, 能否在 Go Playground 上展示一个更完整的示例?因为我现在不太清楚具体的实现方式。

// 示例代码将在此处显示

很高兴这很有帮助…… 表情符号

func main() {
    fmt.Println("hello world")
}

当有多个选择项时,我们如何在范围内识别它们? 因为如果我像示例中那样在点后面放置fruit,选择结果会是空的

是的。实际上,您引用的网页使用了 html/template。

<select> // for loop in html template example

{{range $key, $value := .}} {{ $key }} {{end}}

在你的选择器中需要有两个值:一个作为键,另一个作为选项显示的值。

由于你使用的是映射(map),可以将映射的键用作选项的键。

值可以是根据映射中的数据构建的字符串表达式。

若要使某个选项默认被选中,请在该选项上添加 selected="selected" 子句。

可能解析器没有正确理解你的模板。请改为:

<select>
{{- range $key, $value := .}}
<option value="{{ $key }}">{{ $value }}</option>
{{- end}}
</select>

同时将输出生成到标准输出以检查是否正确:

t.Execute(os.Stdout, fruits)
t.Execute(w, fruits)

你可以使用接口映射而不会出现问题。对你来说更简单的方法是将所有需要的变量分组到一个结构中。例如:

iewData := struct {
	Fruits map[string]interface{}
}{
	fruits,
}

t.Execute(os.Stdout, viewData)
t.Execute(w, viewData)

在你的模板中

<select>
  {{- range $key, $value := .Fruits}}
  <option value="{{ $key }}">{{ $value }}</option>
  {{- end}}
</select>

你好 Yamil_Bracho,

我测试过了,但它不起作用。 如果我不使用这个函数,但如果我有更多像这样的模型,如何知道它会采用哪个? 这个可以工作:

<select>
{{- range $key, $value := .}}
<option value="{{ $key }}">{{ $value }}</option>
{{- end}}
</select>

为什么这个不行?

 <select>
{{- range $key, $value := .fruits}}
<option value="{{ $key }}">{{ $value }}</option>
{{- end}}
</select>

好的,这是我的HTML代码

<select>
{{range $key, $value := . fruits}}
 <option value="{{ $value }}">{{ $key }}</option>

除非我删除fruit,否则选择框会是空的。我不明白如何调用fruit,因为如果你有更多选择框,这样写就不起作用

package main
import (
"html/template"
"net/http"
 )
var fruits = map[string]interface{}{
"Apple":  "apple",
"Orange": "orange",
"Pear":   "pear",
"Grape":  "grape",
}

func handler(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("templates/view.html")
if err != nil {
	panic(err)
}

t.Execute(w, fruits)
}

func main() {

http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}

感谢您的耐心和解释

类似这样的代码::

package main

import (
	"net/http"
	"html/template"
)

var fruits = map[string]interface{}{
	 "Apple":  "apple",
	 "Orange": "orange",
	 "Pear":   "pear",
	 "Grape":  "grape",
}

func Handler(w http.ResponseWriter, r *http.Request) {
   t, err := template.ParseFiles("view.html") 
   if err != nil {
	 panic(err)
   }
   
   t.Execute(w, fruits)
}

func main() {

  http.HandleFunc("/view", Handler)
  http.ListenAndServe(":8080", nil)
}
<html>
<head>
  <title>First Program</title>
</head>
<body>
  <select>
	 {{range $key, $value : =.Fruits }} 
	 <option>{{ $key}}</option>
	 {{end}}
   </select>
</body>
</html>

好的,我明白了语法有问题,请告诉我这样写是否正确

package main
import (
"net/http"
"html/template"
)
var fruits = map[string]interface{}{
    "Apple":  "apple",
    "Orange": "orange",
    "Pear":   "pear",
    "Grape":  "grape",
}

func handler(w http.ResponseWriter, r *http.Request) {
t, _ := template.ParseFiles("view.html") //步骤1
t.Execute(w, fruits) //步骤2
}

func main() {
server := http.Server{
    Addr: "127.0.0.1:8080",
}
http.HandleFunc("/view", handler)
server.ListenAndServe()
}

view.html的HTML代码:

<html>
<head>
  <title>First Program</title>
  </head>
  <body>
  <select>{{range $ key, $ value: =. Fruits}} <option>{{$ key}} </option></select>
  {{end}}
  </body>

你觉得我这样处理是否不太妥当?

好的,这个方法可行,但我不确定这是否是正确的做法。

<select>
	{{range .Fruits}}
	<option value="{{ .Name }}">{{ .Values }}</option>
	{{end}}
</select>

所以我没有使用接口映射

package main
import (
"html/template"
"net/http"
)
type Fruit struct {
Name   string
Values string
}
type Data struct {
Name   string
Fruits []Fruit
}
func main() {

http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("templates/view.html")
if err != nil {
	panic(err)
}
//t.Execute(os.Stdout, Data)

t.Execute(w, Data{
	Fruits: []Fruit{
		Fruit{"Apple", "apple"},
		Fruit{"Orange", "orange"},
	},
})
}

如何使用接口映射获得相同的结果?答案并不简单

当然。

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
Fruits:
<select>
{{- range $key, $value := .Fruits}}
<option value="{{ $key }}">{{ $value }}</option>
{{- end}}
</select>
</body>
</html>

Go

package main

import (
"html/template"
"net/http"
"os"
)

var fruits = map[string]interface{}{
"Apple":  "apple",
"Orange": "orange",
"Pear":   "pear",
"Grape":  "grape",
}

func handler(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("templates/view.html")
if err != nil {
panic(err)
}

viewData := struct {
	Fruits map[string]interface{}
}{
	fruits,
}

//t.Execute(os.Stdout, viewData)
t.Execute(w, viewData)
}

func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}

在Go语言中,可以使用HTML模板和map接口动态填充下拉菜单,同时保持代码结构分离。以下是一个示例,展示如何将页眉、页脚和内容拆分为独立的模板文件,并通过map数据填充下拉菜单。

首先,假设你有以下目录结构:

templates/
  header.html
  content.html
  footer.html
  1. header.html(页眉模板):
<!DOCTYPE html>
<html>
<head>
    <title>下拉菜单示例</title>
</head>
<body>
  1. content.html(内容模板,包含下拉菜单):
<h1>选择选项</h1>
<form method="post">
    <select name="options">
        {{range $key, $value := .Options}}
        <option value="{{$key}}">{{$value}}</option>
        {{end}}
    </select>
    <input type="submit" value="提交">
</form>
  1. footer.html(页脚模板):
</body>
</html>

在Go代码中,使用template.ParseFiles加载所有模板文件,并传递一个map作为数据。示例代码如下:

package main

import (
    "html/template"
    "net/http"
)

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
    // 定义map数据,用于填充下拉菜单
    optionsMap := map[string]string{
        "opt1": "选项一",
        "opt2": "选项二",
        "opt3": "选项三",
    }

    // 解析所有模板文件
    tmpl, err := template.ParseFiles("templates/header.html", "templates/content.html", "templates/footer.html")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // 准备模板数据
    data := struct {
        Options map[string]string
    }{
        Options: optionsMap,
    }

    // 执行模板,将数据注入
    err = tmpl.Execute(w, data)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

在这个示例中:

  • header.htmlcontent.htmlfooter.html是分离的模板文件,便于维护。
  • 在Go代码中,通过template.ParseFiles加载所有模板文件,它们会自动合并。
  • 使用一个结构体传递数据到模板,其中Options字段是map接口,模板中的{{range}}循环遍历map并生成<option>元素。

运行此代码后,访问http://localhost:8080将显示一个下拉菜单,包含map中的选项。这种方法避免了在代码中硬编码HTML,实现了内容与结构的分离。如果map数据来自数据库或其他动态源,只需更新optionsMap即可。

回到顶部