如何处理使用 Revel Golang 的 HTML 表单中的动态数量的输入?

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

How to handle dynamic number of inputs from html form with with Revel Golang

问题

我有一个带有动态数量输入的HTML表单。每个输入都必须是一个Model对象,我还有一个函数,用于接收这些输入的值。

我的HTML表单:

  1. <form action="{{url "Votes.CreateVote"}}" id="formVoteCreate" method="POST">
  2. <p class="field">
  3. <label>Question:</label>
  4. <input type="text" name="question" size="40" />
  5. </p>
  6. <div ng-repeat="answer in answers">
  7. <p class="field">
  8. <label>//stuff.title//:</label>
  9. <input type="text" name=//stuff.name// size="40" />
  10. </p>
  11. </div>
  12. <p>
  13. <input ng-click="addInput()" class="btn" type="button" value="Add answer">
  14. </p>
  15. <p class="buttons">
  16. <input class="btn" type="submit" value="Create" />
  17. </p>
  18. </form>

以及Revel框架的Go语言处理程序:

  1. func (c Votes) CreateVote() revel.Result {
  2. // 在这个位置,我想从HTML表单中获取一个包含答案的切片
  3. return c.Redirect(routes.App.Index())
  4. }

还有答案模型:

  1. type Answer struct {
  2. Model
  3. Text string
  4. }

我该如何将表单的值作为一个包含答案的切片发送,并打包到Model中?

英文:

I have an html form with dynamic number of inputs. Each input must be a Model object, and i also have a function, which receives values from this inputs.
My html form:

  1. &lt;form action=&quot;{{url &quot;Votes.CreateVote&quot;}}&quot; id=&quot;formVoteCreate&quot; method=&quot;POST&quot;&gt;
  2. &lt;p class=&quot;field&quot;&gt;
  3. &lt;label&gt;Question:&lt;/label&gt;
  4. &lt;input type=&quot;text&quot; name=&quot;question&quot; size=&quot;40&quot; /&gt;
  5. &lt;/p&gt;
  6. &lt;div ng-repeat=&quot;answer in answers&quot;&gt;
  7. &lt;p class=&quot;field&quot;&gt;
  8. &lt;label&gt;//stuff.title//:&lt;/label&gt;
  9. &lt;input type=&quot;text&quot; name=//stuff.name// size=&quot;40&quot; /&gt;
  10. &lt;/p&gt;
  11. &lt;/div&gt;
  12. &lt;p&gt;
  13. &lt;input ng-click=&quot;addInput()&quot; class=&quot;btn&quot; type=&quot;button&quot; value=&quot;Add answer&quot;&gt;
  14. &lt;/p&gt;
  15. &lt;p class=&quot;buttons&quot;&gt;
  16. &lt;input class=&quot;btn&quot; type=&quot;submit&quot; value=&quot;Create&quot; /&gt;
  17. &lt;/p&gt;
  18. &lt;/form&gt;

And revel golang handler:

  1. func (c Votes) CreateVote() revel.Result {
  2. // in this place i want get a slice with answers from html form
  3. return c.Redirect(routes.App.Index())
  4. }

and answer model:

  1. type Answer struct {
  2. Model
  3. Text string
  4. }

How can i send form's values as a slice with answers packed to Model?

答案1

得分: 1

每个Revel控制器都附带一个附加的Request,它实际上只是一个普通的Go标准库Request。因此,与普通的Go Web服务器一样,我们不能使用Request.Form.Get("inputname")方法,因为这只会给出第一个结果。相反,我们需要直接访问Form映射中的值:

  1. package controllers
  2. import (
  3. "log"
  4. "github.com/robfig/revel"
  5. )
  6. type App struct {
  7. *revel.Controller
  8. }
  9. func (c App) Index() revel.Result {
  10. if err := c.Request.ParseForm(); err != nil {
  11. // 处理错误
  12. }
  13. values := c.Request.Form["text"]
  14. for i := range values {
  15. log.Println(values[i])
  16. }
  17. return c.Render()
  18. }

上面的示例是一个简单的应用程序,就像在启动项目时Revel生成的应用程序一样,其中有一个名为text的输入,并且可以根据您的特定情况进行调整。

values变量的类型是[]string,因此,如果您提交一个带有查询字符串?text=value1&amp;text=value2&amp;text=value3的GET请求,就像使用method="GET"和三个name="text"的文本输入的表单一样,将会记录如下内容:

  1. 2016/03/07 22:16:41 app.go:19: value1
  2. 2016/03/07 22:16:41 app.go:19: value2
  3. 2016/03/07 22:16:41 app.go:19: value3

问题中的表单恰好使用POST方法,但从表单中读取值的代码保持不变。

英文:

Each Revel controller comes with an attached Request, which is really just a normal Go standard library Request. As such, this is the same as for plain Go web servers, in that we cannot use the Request.Form.Get(&quot;inputname&quot;) method, as this would only give the first result. Instead, we need to access the values in the Form map directly:

  1. package controllers
  2. import (
  3. &quot;log&quot;
  4. &quot;github.com/robfig/revel&quot;
  5. )
  6. type App struct {
  7. *revel.Controller
  8. }
  9. func (c App) Index() revel.Result {
  10. if err := c.Request.ParseForm(); err != nil {
  11. // handle error
  12. }
  13. values := c.Request.Form[&quot;text&quot;]
  14. for i := range values {
  15. log.Println(values[i])
  16. }
  17. return c.Render()
  18. }

The example above is for a simple application like the one generated by Revel when you start a project, with an input named text, and can be adapted to your specific case.

The values variable is of type []string, which is why the following is logged, if you submit a GET request with query string ?text=value1&amp;text=value2&amp;text=value3, as would happen for a form with method=&quot;GET&quot; and three text inputs with name=&quot;text&quot;:

  1. 2016/03/07 22:16:41 app.go:19: value1
  2. 2016/03/07 22:16:41 app.go:19: value2
  3. 2016/03/07 22:16:41 app.go:19: value3

The form in the question happens to use method POST, but the code for reading the values from the form remains the same.

huangapple
  • 本文由 发表于 2016年3月7日 19:57:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/35843156.html
匿名

发表评论

匿名网友

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

确定