Golang模板范围(for循环)使用来自WebSocket的JSON [英] Golang Template Range (for loop) using JSON from WebSocket

查看:274
本文介绍了Golang模板范围(for循环)使用来自WebSocket的JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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; (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的id中看到0,我应该注意它更长,但是我试图只采取相关的部分..



当然我不想手动键入HTML,因为它会使处理不同的长度变得困难(/不可能)像有时候我想显示一百个应用程序,其他时间也许只有3个可用,等等。)



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

另一个应该可管理的解决方案是只需在 ws.onmessage 中写出JS for循环中的所有HTML,但我认为如果我使用golang模板包学会了如何做,那会更好。特别是因为它真的很长,并且有许多class / id。

我看到它的方式,我需要得到JSON的长度( Object.k eys(d).length; ),然后以某种方式我需要在{{range}}中传递此长度,然后可以使用{{index}}通过JSON对象进行交互。



..但我一直无法弄清楚如何去做,也许这是不可能的..我将不胜感激任何帮助如何做到这一点..

解决方案

一种简单的方法是在服务器上执行一个模板,并将生成的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>
{{。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 {
//处理错误
}
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。

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

解决方案

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.

这篇关于Golang模板范围(for循环)使用来自WebSocket的JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆