【发布时间】:2017-07-28 05:10:34
【问题描述】:
我的情况是,我想将未知数量的输入值放入我的 Go 结构中,但只有其中一些会被放置在切片/数组中。这是 HTML 内容的 sn-p:
<form action="/" method="post">
...
<tbody>
{{ range .users }}
<tr>
<td class="text-center">
<img class="avatar" src="{{ .AvatarThumbnailURL }}">
<input type="hidden" name="thumbnail" value="{{ .AvatarThumbnailURL }}">
</td>
<td>
{{ .Username }}<input type="hidden" name="username" value="{{ .Username }}">
</td>
<td>
{{ .Age }}<input type="hidden" name="age" value="{{ .Age }}">
</td>
<td>
{{ .Email }}<input type="hidden" name="email" value="{{ .Email }}">
</td>
</tr>
<input type="hidden" name="userid" value="{{ .UserID }}">
{{end}}
</tbody>
...
{{ .csrfField }}
// submit button
</form>
{{ .csrfField }} 将生成隐藏输入。这部分工作正常。
现在的问题是如何在结构中获取这些数据?
假设我有以下结构:
type UserFormData struct {
UserID int
Username string
AvatarThumbnailURL string
Age int
Email string
}
但是在我的 POST 函数中,我不知道有多少用户会通过表单提交。所以我想我必须这样做:
userFormData := make([]UserFormData, len(r.PostForm)/6)
(除以6,因为有AvatarThumbnailURL、Username、Age、Email、UserID和csrfField)
然后可以像这样遍历r.PostForm:
i := 0
j := 0
for key, values := range r.PostForm {
switch key {
case "userid":
userid, _ := strconv.Atoi(values[0])
userFormData[j].UserID = userid
case "thumbnail":
userFormData[j].Thumbnail = values[0]
// the other fields
i++
if i%6 == 0 {
j++
}
}
虽然这项工作很容易出现 indexoutofrange 错误,并且每当我进行更改时,我都必须计算将与表单一起发送的输入值的数量并更新(当前)“6”值。我毫不怀疑必须有一种非常非常好的方法来做到这一点,如果有人能指出我正确的方向,我将不胜感激:)
【问题讨论】:
-
完全可能有更好的方法,但这至少可以避免使用幻数来知道有多少结构字段。 golang.org/pkg/reflect/#Value.NumField
-
问题。如果你的范围超过
.users,那你不知道会提交多少用户?您不能再包含一个隐藏字段,其中包含表单上有多少用户? -
无法保证浏览器会按照它们在 HTML 中出现的顺序提交表单字段,因此为了安全起见,您可能需要在字段名称中附加一个标识符以确保您可以正确相关的相关字段。