使用来自WebSocket的JSON的Golang模板范围(for循环)

时间:2017-02-17 23:14:44

标签: javascript html5 go websocket go-html-template

我使用Gorilla Websocket更新一些HTML(img src,text等);我这样做的方式如下:

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
}

然后我使用javascript以这种方式更新HTML数据:

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;
    }
  };

然后我以这种方式手动输入HTML:

<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>

你可以在HTML&#39; id中看到0,我应该注意它的时间要长得多,但我只是尝试了相关的部分..

我当然希望不要手动输入HTML,因为它会使处理不同长度变得困难(或者不可能)(例如,有时候我想显示一百个应用程序,其他时候可能只有3个可用,等等..)

我在想这可能是使用golang的HTML {{range}}函数完成的,但我无法弄清楚如何将它与来自websockets的json数据集成。

另一个应该是可管理的解决方案就是在ws.onmessage处写出JS for循环内的所有HTML,但我认为如果我学会了如何使用golang模板包进行操作会更好。特别是因为它真的很长,并且有许多课程/内容......

我看到它的方式,我需要得到JSON的长度(Object.keys(d).length;),然后我需要在{{range}}内传递这个长度,然后可以使用{{index}}来通过JSON对象进行交互..

..但我还没有弄清楚如何去做,也许它甚至不可能......我非常感谢任何有关如何做到这一点的帮助..

1 个答案:

答案 0 :(得分:0)

一种简单的方法是在服务器上执行模板,并将生成的HTML发送到将HTML插入页面的客户端。

使用已编译的模板声明包级别变量。 此模板假定Execute的参数是一个切片 带有字段ThumbnailURL,标题和兼容性的结构或地图。

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}}`))

在读取循环中执行模板。将HTML发送到客户端:

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
}

在页面上包含结果的div:

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

收到消息时设置div的内部HTML:

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

此解决方案不使用JSON。