2017-02-17 44 views
0

我使用Gorilla Websocket来更新一些HTML(img src,text等);我这个做如下方式:Golang使用来自WebSocket的JSON的模板范围(for循环)

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'ID中看到0,我应该注意它更长,但我试图只拿相关部分。我当然不想手动输入HTML,因为它会使处理不同的长度变得困难(或不可能)(例如,有时我想显示一百个应用程序,其他时间也许只有三个可用,等等。 )

我想这可能是能够使用golang的HTML {{范围}}函数来完成,但我无法弄清楚如何将它与WebSockets的JSON数据整合..

另一种解决方案,应该是可管理的,只是写出所有的HTML内部的JS循环在ws.onmessage,但我认为这将是更好,如果我学会了如何使用golang模板包。特别是因为它很长,并且有很多类/编号是..

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

..但我一直无法弄清楚如何做到这一点,也许它甚至没有可能。我将不胜感激着如何可以做到这一点任何帮助..

+0

这看起来像你应该从JavaScript做的事情。您可以使用'document.createElement()'动态创建新元素。从代码动态创建DOM非常普遍,因此存在一个框架ReactJS。 –

+0

嗯,我也在研究document.createElement/jquery解决方案,因为我无法弄清楚如何使用golang模板包来完成它,只是感觉它是一团糟。我也一直在努力是否将ReactJS整合到项目中,因为我担心学习起来太费时了..但是我想这将是值得的。谢谢 – fisker

回答

0

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

声明已编译模板的包级变量。 此模板假定执行参数是 结构或映射的片段,其中包含字段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。

+0

哇,这真是太好了,正是我所希望的可能而不是用jquery/document.createElement来做。非常感谢你! – fisker