Echo Framework Bind () HTML FormData - PullRequest
       2

Echo Framework Bind () HTML FormData

0 голосов
/ 28 января 2019

У меня есть форма HTML как:

<input name="email"type="email" />
<input name="password"type="password" />
<input name="tags[name][]"type="text" />
<input name="tags[count][]"type="number" />
<input name="tags[name][]"type="text" />
<input name="tags[count][]"type="number" />
<input name="tags[name][]"type="text" />
<input name="tags[count][]"type="number" />
<input name="freeword[]"type="text" />
<input name="freeword[]"type="text" />

Я хочу Bind() эту форму с моим struct, как:

type UserFrom struct {
  Email string `json:"email" form:"email" query:"email"`
  Password string `json:"password" form:"password" query:"password"`
  Tags []Tag
  Free []string `json:"freeword[]" form:"freeword[]" query:"freeword[]"`
}
type Tag struct {
  Name string `json:"tags[name][]" form:"tags[name][]" query:"tags[name][]"`
  Count string `json:"tags[count][]" form:"tags[count][]" query:"tags[count][]"`
}

Но если я напечатаю результатBind() после POST у меня есть:

u := new(UserFrom)
if err = c.Bind(u); err != nil {
  return
}
log.Println(u)

Этот плохой вывод:

&{email@mail.tld pwdpwdpwd [] [word1 word2]}

Строка Tags []Tag в UserFrom struct не работает

Если вы попытаетесь изменить Tags []Tag на Tags Tag, у меня будет хорошая последняя запись

&{email@mail.tld pwdpwdpwd {tag3 3} [word1 word2]}

Я хочу этот вывод:

&{email@mail.tld pwdpwdpwd [{tag1 1} {tag2 2} {tag3 3}] [word1 word2]}

У вас есть представление о проблеме?

Echo Doc to Bind ()

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Thx @ alexaandru для вашего ответа,

У меня есть поля формы обновления:

<input name="tags[][name]"type="text" />
<input name="tags[][count]"type="number" />
<input name="tags[][name]"type="text" />
<input name="tags[][count]"type="number" />
<input name="tags[][name]"type="text" />
<input name="tags[][count]"type="number" />

И я должен создать простое for

u := new(UserForm)
if err := c.Bind(u); err != nil {

}

fiels, _ := c.FormParams()
var tags []Tag
var tag Tag
for i := 0; i < len(fiels["tags[]tag"]); i++ {
    count, _ := strconv.Atoi(fiels["tags[][count]"][i])

    tag.Name = fiels["tags[][name]"][i]
    tag.Comment = count

    tags = append(tags, tag)

}

u.Tags = tags
log.Println(u)

У меня хороший вывод:

&{email@mail.tld pwdpwdpwd [{tagX 1} {tagY 2} {tagZ 3}] [wordX wordY]}
0 голосов
/ 29 января 2019

Есть две проблемы:

  1. вы неправильно указали имена для ввода в форме, то, как они у вас, никогда не могут быть сопоставлены с тем, что вы хотите на любом языке.В языках, которые поддерживают то, что вы хотите, теги будут отображаться в структуре из двух полей (name и count), каждое из которых состоит из массива.Не к массиву структур имени и количества.Имена должны быть такими: tags[][name], чтобы достичь желаемого, смотрите здесь, например: Форма HTML: POST массив объектов
  2. , даже если вы правильно указали имя согласновыше, в любом случае это не будет работать в Echo, так как он использует http.Request.Form для анализа значений, что фактически составляет url.Values, что, в свою очередь, является просто map[string][]string.Как видите, это не может охватить структуру, которую вы хотите.Вот соответствующий тикет: https://github.com/golang/go/issues/29703

Теперь, просто потому что Echo не поддерживает это из коробки, это не значит, что вы не можете это сделать.Вы можете использовать стороннюю библиотеку для связывания, которая обладает необходимыми функциями, такими как https://github.com/monoculum/formam

Следующий код:

package main

import (
    "fmt"
    "net/url"

    "github.com/monoculum/formam"
)

type User struct {
    Email,
    Password string
    Tags []struct {
        Tag   string
        Count int
    }
}

func main() {
    formData := "Email=joe@example.com&Password=secret&Tags[0].Tag=red&" + 
        "Tags[0].Count=1&Tags[1].Tag=blue"
    q, _ := url.ParseQuery(formData)
    u := new(User)

    dec := formam.NewDecoder(nil)
    if err := dec.Decode(q, u); err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println(u)
}

приводит к тому, что вам нужно:

&{joe@example.com secret [{red 1} {blue 0}]}

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...