douwei7976 2015-09-28 04:09
浏览 42
已采纳

使用绑定解析数组表单元素

I am trying to submit and parse a form in go and I am failing to parse the form fields properly. Here is an excerpt of the code I am trying.

formtest.go : package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/codegangsta/negroni"
    "github.com/davecgh/go-spew/spew"
    "github.com/julienschmidt/httprouter"
    "github.com/mholt/binding"
    "gopkg.in/unrolled/render.v1"
)

type FormInfo struct {
    Fields    []string
    Action    string
    PageTitle string
    Id        string
}

func (f *FormInfo) FieldMap(*http.Request) binding.FieldMap {
    return binding.FieldMap{
        &f.Fields: "fields",
        &f.Action: "action",
    }
}

func formtest(
    resp http.ResponseWriter,
    req *http.Request,
    p httprouter.Params) {

    // var ticket Ticket
    info := new(FormInfo)
    tkt := p.ByName("tkt")
    info.PageTitle = tkt
    info.Id = tkt

    if req.Method == "POST" {
        bind_err := binding.Bind(req, info)
        if bind_err.Handle(resp) {
            log.Println("Error decoding form contents")
            return
        }
        spew.Dump(info)
    }

    Render.HTML(resp, http.StatusOK, "formtest", info)
    return
}

var Render *render.Render

func main() {

    router := httprouter.New()

    router.GET("/formtest", formtest)
    router.POST("/formtest", formtest)

    Render = render.New(render.Options{
        Layout:          "layout",
        IndentJSON:      true,
        IndentXML:       true,
        HTMLContentType: "text/html",
        IsDevelopment:   true,
    })

    n := negroni.New(
        negroni.NewRecovery(),
        negroni.NewLogger(),
        negroni.NewStatic(http.Dir("static")),
    )
    n.UseHandler(router)
    n.Run(fmt.Sprintf(":%d", 3000))

}

templates/layout.tmpl :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>{{ .PageTitle }}</title>
    <meta http-equiv="Content-Type" content="text/html;" charset="utf-8">
    <meta charset="UTF-8">
    <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
    <link rel="apple-touch-icon" href="/mobile.png" />
    <meta name="viewport" 
          content="initial-scale=1.0,width=device-width,user-scalable=no">
    <meta name="generator" content="Go">
    <link rel="stylesheet" href="/base.css" type="text/css">
  </head>

  <body>

      <div class="mainbody">
        {{ yield }}
      </div>

  </body>

</html>

templates/formtest.tmpl :

<h1>{{ .PageTitle }}</h1>

<form action="/formtest/{{ .Id }}" method="POST">

    <div class="details">
      <label>Question 1</label>
      <input type="text" name="fields[0]" value="value 1" />
    </div>

    <div class="details">
      <label>Question 2</label>
      <input type="text" name="fields[1]" value="value 2" />
    </div>

    <div class="details">
      <input type="submit" name="action" value="save" />
    </div>

</form>

Procedure:

  1. go run formtest.go
  2. Open browser and go to http://127.0.0.1:3000/formtest
  3. Submit the form
  4. Check console for the logs.

Observation :

(*main.FormInfo)(0xc820066c30)({
 Fields: ([]string) <nil>,
 Action: (string) (len=4) "save",
 PageTitle: (string) "",
 Id: (string) ""
})

Expectation :

Fields: ([]string) <contains two values submitted>,

But when I try to print the contents of Fields, it is nil. What am I doing wrong?

  • 写回答

1条回答 默认 最新

  • douwu3763 2015-09-28 23:59
    关注

    Binding so not work. The fields of your form - name = "fields [1]" and name = "fields [0]" are independent from each other, so for each of them your structure should contain its own field:

    type FormInfo struct {
        Fields1   string
        Fields2   string
        Action    string
        PageTitle string
        Id        string
    }
    

    respectively, in the handler:

    ...
    &f.Fields1: "fields[0]",
    &f.Fields2: "fields[1]",
    &f.Action:  "action",
    ...
    

    As a result, the output will be:

    (*main.FormInfo)(0xc08200aa50)({
     Fields1: (string) (len=7) "value 1",
     Fields2: (string) (len=7) "value 2",
     Action: (string) (len=4) "save",
     PageTitle: (string) "",
     Id: (string) ""
    })
    

    EDIT:

    If you change the code in the form on the

    ...
    <input type="text" name="fields"...
    <input type="text" name="fields"...
    

    you can get

    info.Fields = [value 1 value 2]
    

    without changing its original code.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 matlab求解平差
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊
  • ¥15 安装svn网络有问题怎么办