douyuqing_12345 2017-02-17 23:14
浏览 135
已采纳

从WebSocket使用JSON的Golang模板范围(用于循环)

I'm using Gorilla Websocket to update some HTML (img src, text, etc); I do this the following way:

mt, message, err := c.ReadMessage()
if err != nil {
    log.Println("read:", err)
    break
}
[...]
app, err := models.DB.SearchAppStore(ctx, stars, updatedWithin, 0)
myJson, err := json.Marshal(app)
err = c.WriteMessage(mt, myJson)
if err != nil {
    log.Println("write:", err)
    break
}

Then I use javascript to update the HTML data this way:

ws.onmessage = function(evt) {
    var d = JSON.parse(evt.data);
    var app;
    for (app = 0; app < 3; app++) {
      document.getElementById("app-icon-" + app).src = d[app].ThumbnailURL;
      document.getElementById("app-title-" + app).innerHTML = d[app].Title;
      document.getElementById("app-compatibility-" + app).innerHTML = d[app].Compatibility;
    }
  };

And then I have manually typed the HTML this way:

<div class="app-section">
  <div class="icon">
    <img src="" id="app-icon-0">
  </div>
  <div class="details">
    <h2 id="app-title-0"></h2>
    <h5 id="app-compatibility-0"></h5>
  </div>
</div>

You can see the 0 in the HTML 'id's, and I should note that it's much longer but I tried to only take the relevant parts..

I would of course like not to type HTML manually since it will make it difficult(/impossible) to deal with different lenghts (like maybe sometimes I want to display a hundred apps, other times maybe there only are 3 available, etc..)

I was thinking this might be able to be done using golang's HTML {{range}} function, but I can't figure out how to integrate it with json data from websockets..

Another solution that should be managable is to just write out all the HTML inside the JS for loop at ws.onmessage, but I think it would be better if I learned how to do it using the golang template package.. Especially because it's really long and there are many classes/id's..

The way I see it, I need to get the length of the JSON (Object.keys(d).length;), then somehow I need to pass this length inside {{range}} and then can use {{index}} to interate through the JSON object..

..but I haven't been able to figure out how to do it, maybe it's not even possible.. I would greatly appreciate any help with how this can be done..

  • 写回答

1条回答 默认 最新

  • drduinfu915094 2017-02-18 03:32
    关注

    A simple approach is to execute a template on the server and send the resulting HTML to the client where the HTML is inserted into the page.

    Declare package level variable with compiled template. This template assumes that the argument to Execute is a slice of structs or maps with fields ThumbnailURL, Title and Compatibility.

    var t = template.Must(template.New("").Parse(`{{range .}}
      <div class="icon">
       <img src="{{.ThumbnailURL}}">
      </div>
      <div class="details">
       <h2>{{.Title}}</h2>
       <h5>{{.Compatibility}}</h5>
      </div>{{end}}`))
    

    Execute the template in your read loop. Send the HTML to the client:

    mt, message, err := c.ReadMessage()
    if err != nil {
       log.Println("read:", err)
       break
    ]
    [...]
    app, err := models.DB.SearchAppStore(ctx, stars, updatedWithin, 0)
    var buf bytes.Buffer
    if err := t.Execute(&buf, app); err != nil {
        // handle error
    }
    err = c.WriteMessage(mt, buf.Bytes())
    if err != nil {
      log.Println("write:", err)
      break
    }
    

    Include a div for the results on the page:

    <div class="app-section"></div>
    

    Set the div's inner HTML when a message is received:

    ws.onmessage = function(evt) {
        document.getElementById("app-section").innerHTML = evt.Data;
    }
    

    This solution does not use JSON.

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

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料