Javascript 是否可以使用RESTAPI将Go函数绑定到web GUI?

Javascript 是否可以使用RESTAPI将Go函数绑定到web GUI?,javascript,html,rest,go,Javascript,Html,Rest,Go,我试图创建一个具有前端和后端的web应用程序,其中go应用程序是后端,而(带有Javascript的HTML)web页面是前端。 我想做的一件(看起来)简单的事情,就是在webgui中按下一个按钮,在go应用程序中点击这个按钮,然后用它做一些事情。我想做的第二件事是根据我在go应用程序中的操作更新网页 为此,我在网上搜索了一些有趣的教程,并采用了(或多或少)相同的方法:在GO中使用restfulapi,使用Json格式编写和读取数据。虽然我必须说这很有趣,但我并没有成功地将其用于我的目的。(或者

我试图创建一个具有前端和后端的web应用程序,其中go应用程序是后端,而(带有Javascript的HTML)web页面是前端。 我想做的一件(看起来)简单的事情,就是在webgui中按下一个按钮,在go应用程序中点击这个按钮,然后用它做一些事情。我想做的第二件事是根据我在go应用程序中的操作更新网页

为此,我在网上搜索了一些有趣的教程,并采用了(或多或少)相同的方法:在GO中使用restfulapi,使用Json格式编写和读取数据。虽然我必须说这很有趣,但我并没有成功地将其用于我的目的。(或者也许我只是不够聪明,不能按照自己的目的来调整它;))。不管怎样,我被卡住了

到目前为止,我拥有的是(Go):

和HTML:

<!DOCTYPE html>
<html lang="en">

<head>
  <title>test app</title>
</head>

<body>
  <h1>test app</h1>
  <br/>
  <script>
    fetch("/test")
      .then(response => response.json())
      .then(sgList => {
        //Once we fetch the list, we iterate over it
        sgList.forEach(person => {
          //Create an input type dynamically.
          var btn = document.createbutton("BUTTON");
          btn.innerHTML = person.name;
          document.body.appendChild(btn);
        })
      })
  </script>
</body>
</html>

测试应用程序
测试应用程序

获取(“/test”) .then(response=>response.json()) 。然后(sgList=>{ //获取列表后,我们将对其进行迭代 sgList.forEach(person=>{ //动态创建输入类型。 var btn=document.createbutton(“按钮”); btn.innerHTML=person.name; 文件.正文.附件(btn); }) })
我的问题: 我可以在HTML网页上创建尽可能多的按钮吗? 我可以让这些按钮与我的go应用程序交互吗


如果我不可能得到我想要的,还有什么选择?(如果可能的话,我想继续使用GO)。

看起来GO有几个问题需要解决,然后才能恢复数据

  • 您的Person_t类属性(姓名、年龄)需要以大写字母开头才能正确编组。在go中,不会导出任何小写变量,因此json编组包需要能够看到它才能读取接口

  • 您需要封送数据并将其写入responsewriter,以便前端查看

  • 此版本应返回可用于与前端组件集成的json

    package main
    
    import (
      "encoding/json"
      "fmt"
      "net/http"
    
      "github.com/gorilla/mux"
    )
    
    type Person_t struct {
      Name string `json:"name"`
      Age  int    `json:"age"`
    }
    
    var Persons []Person_t
    
    // !!! I need to do something here, but don't know what !!!
    func TestFunc(w http.ResponseWriter, r *http.Request) {
    
      err := r.ParseForm()
    
      if err != nil {
        fmt.Println(fmt.Errorf("error: %v", err))
        w.WriteHeader(http.StatusInternalServerError)
        return
      }
    
      jsData, err := json.Marshal(Persons)
      if err != nil {
        fmt.Println(fmt.Errorf("error: %v", err))
        w.WriteHeader(http.StatusInternalServerError)
        return
      }
      w.Header().Add("Content-Type", "application/json")
      w.Write(jsData)
    }
    
    // router functionality
    func newRouter() *mux.Router {
      r := mux.NewRouter()
    
      staticFileDirectory := http.Dir("./assets/")
      staticFileHandler := http.StripPrefix("/assets/", http.FileServer(staticFileDirectory))
      r.PathPrefix("/assets/").Handler(staticFileHandler).Methods("GET")
    
      r.HandleFunc("/test", TestFunc).Methods("POST")
    
      return r
    }
    
    func webServer() {
      r := newRouter()
      http.ListenAndServe(":8080", r)
    }
    
    func main() {
    
      /* some data */
      Persons = []Person_t{
        {Name: "Piet", Age: 22},
        {Name: "Kees", Age: 23},
        {Name: "Klaas", Age: 24},
      }
    
      webServer()
    }
    
    请注意,前端可能还需要一些更健壮的东西来解析响应并为每个响应动态构建表单。我建议使用一种简单的方法,在构造函数中调用/test端点,并在呈现中迭代json响应,即

    getPersons() {
        fetch("/test")
          .then(response => response.json())
          .then(sgList => {
            this.state.persons = sgList
          })
      }
    
      render() {
        return (
          {
            this.state.persons || null ? this.state.persons.map((person => (
              <form onSubmit={this.handleSubmit}>
                <label>
                  Name: {person.name}
                  <input type="text" value={person.age} onChange={this.handleChange} />
                </label>
                <input type="submit" value="Submit" />
              </form>
            ))) : null
          }
        );
      }
    
    getPersons(){
    获取(“/test”)
    .then(response=>response.json())
    。然后(sgList=>{
    this.state.persons=sgList
    })
    }
    render(){
    返回(
    {
    this.state.persons | | null?this.state.persons.map((person=>(
    姓名:{person.Name}
    ))):null
    }
    );
    }
    
    可以制作一个能够响应不同请求的go web API—是的。为什么要在
    TestFunc
    中重定向,请参阅这篇关于如何从响应返回JSON的文章
    getPersons() {
        fetch("/test")
          .then(response => response.json())
          .then(sgList => {
            this.state.persons = sgList
          })
      }
    
      render() {
        return (
          {
            this.state.persons || null ? this.state.persons.map((person => (
              <form onSubmit={this.handleSubmit}>
                <label>
                  Name: {person.name}
                  <input type="text" value={person.age} onChange={this.handleChange} />
                </label>
                <input type="submit" value="Submit" />
              </form>
            ))) : null
          }
        );
      }