使用模板在Golang中创建加载更多按钮 [英] Creating load more button in Golang with templates

查看:133
本文介绍了使用模板在Golang中创建加载更多按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个类似Facebook的页面,其中如果用户向下滚动页面获取旧帖子而不刷新。我之前使用Ajax完成了该操作,并使用JS附加了HTML页面。



然而,由于我现在使用Go和它的模板来构建页面,我不确定如何实现类似的结果。请帮助我提供您的建议。

  {{range .posts}} 
<<<括号中,我显示帖子>>
{{end}}
超出范围我创建了加载更多按钮,它调用
内部获取帖子切片的js。

下面的链接显示了一个解决方案,但它不适用于大量数据,创建所有这些按钮js会很困难。
动态刷新模板的一部分,当变量更新时golang



感谢您的帮助。 :)

解决方案

我在您的问题中链接的其他答案包含实现所需的所有详细信息和技巧加载更多...功能:动态刷新模板的一部分,当变量更新时golang



是的,这不是小事,但它是没有那么难/复杂。答案讨论了不同的方式/选择,但显然一个解决方案只需要一个。



这里我展示了一个可行的解决方案。这里的加载更多按钮不会记住返回的最新帖子,它只会检索2个新帖子。考虑如何实现发回最后一个ID,以及何时请求更多请求,然后发送记录。



完整的可运行应用程序代码可以在去游乐场。当然,您不能在Go Playground上运行它,将它保存到本地并在您的计算机上运行。

因此,我们将使用以下 Post entities:

  type Post struct {
User,Time,Text字符串
}

我将使用以下模板:

 < html>< body>< h2>帖子< / h2> 
{{blockbatch。}}
{{range .posts}}
< div>< b> {{。Time}} {{.User}}:< ; / b个{{。文本}}< / DIV>
{{end}}
< div id =nextBatch>< / div>
{{end}}
< button onclick =loadMore()>加载更多< /按钮>
< script>
函数loadMore(){
var e = document.getElementById(nextBatch);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4&& xhr.status == 200){
e.outerHTML = xhr.responseText;


xhr.open(GET,/ posts / more,true);
try {xhr.send(); } catch(err){/ *处理错误* /}
}
< / script>
< / body>< / html>

它包含一个 {{blockbatch。}} < div id =nextBatch> ),并为下一批次呈现一个占位符。接下来,它包含一个加载更多按钮,当按下按钮时,将以渲染的形式提取下一批,并替换占位符。呈现的下一批次还包含下一批次的占位符。



进行AJAX调用的javascript函数详见我链接的另一个答案。



执行此模板的处理程序:

  var t = template.Must(template.New ().Parse(page))

var lastTime = time.Now()

func produceTime()string {
lastTime = lastTime.Add time.Second)
return lastTime.Format(15:04:05)
}

func postsHandler(w http.ResponseWriter,r * http.Request){
//建立一些随机数据进行演示:
data:= map [string] interface {} {posts:[] Post {
{User:Bob,Time:produceTime (),Text:天气很好。},
{User:Alice,Time:produceTime(),Text:正在下雨。},
}}
var err error
switch r.URL.Path {
case/ posts /:
err = t.Execute(w,data)
case/ posts / more :
e rr = t.ExecuteTemplate(w,batch,data)
}
if err!= nil {
log.Printf(Template execution error:%v,err)


$ / code $ / pre>

produceTime()

main()只会产生单调递增的时间戳字符串,所以输出看起来像是合理的。 c>函数来注册处理程序并启动服务器:

$ p $ func main(){
http.HandleFunc( / posts /,postsHandler)
panic(http.ListenAndServe(:8080,nil))
}

就是这样。这是一个可用的应用程序。在浏览器中输入 http:// localhost:8080 / posts / ,您会看到:


帖子



09:42:29 Bob:天气很好。

09:42:30爱丽丝:正在下雨。

加载更多


按下加载更多按钮,浏览器中的内容将被动态刷新,无需重新加载页面。新内容:


文章



09:42:29鲍勃:天气很好。

09:42:30爱丽丝:正在下雨。

09:42:31 Bob:天气很好。

09:42:32爱丽丝:正在下雨。

加载更多

再次按下:


帖子



09:42:29 Bob:天气很好。

09:42:30爱丽丝:正在下雨。

09:42:31鲍勃:天气很好。

09:42:32爱丽丝:正在下雨。

09:42:33鲍勃:天气很好。

09:42:34 Alice:正在下雨。

加载更多



I want to create a Facebook-like page where in if user scroll down the page fetch old post without refreshing. I have done this earlier using Ajax and appending the HTML page using JS.

However, since I am now using Go and its template to build the page, I am not sure how to achieve the similar results. Kindly help me with your suggestion.

{{range .posts}}
 <<in side the range brackets, I am showing the posts >>
{{end}}
out side range I have created load more button which calls 
the js which internally fetch the posts slice.

The link below shows one solution but it will not work for high volume data, creating all those buttons in js will be difficult. Dynamically refresh a part of the template when a variable is updated golang

Thanks for help. :)

解决方案

My other answer you linked in your question contains all the details and tricks you need to implement the "Load more..." functionality: Dynamically refresh a part of the template when a variable is updated golang

Yes, it's not trivial, but it's not that hard / complex either. That answer discusses different ways / alternatives, but obviously a solution only needs one.

Here I show a working solution. The Load more button here will not "remember" what were the last posts returned, it will just retrieve 2 new posts. Think about how you could implement sending back the last ID, and when more is requested, send records following that.

The complete, runnable application code can be found here on the Go Playground. Of course you can't run it on the Go Playground, save it locally and run it on your computer.

So, we'll work with the following Post entities:

type Post struct {
    User, Time, Text string
}

I'm gonna use the following template:

<html><body><h2>Posts</h2>
{{block "batch" .}}
    {{range .posts}}
        <div><b>{{.Time}} {{.User}}:</b> {{.Text}}</div>
    {{end}}
    <div id="nextBatch"></div>
{{end}}
<button onclick="loadMore()">Load more</button>
<script>
    function loadMore() {
        var e = document.getElementById("nextBatch");
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                e.outerHTML = xhr.responseText;
            }
        }
        xhr.open("GET", "/posts/more", true);
        try { xhr.send(); } catch (err) { /* handle error */ }
    }
</script>
</body></html>

It contains a {{block "batch" .}} block for listing posts, and also renders a placeholder for the next batch (<div id="nextBatch">). Next it contains a Load More button, which when pressed, fetches the next batch in a rendered form, and replaces the placeholder. The rendered next batch also contains the placeholder for the next batch.

The javascript function for making an AJAX call is detailed in my linked another answer.

The handler that executes this template:

var t = template.Must(template.New("").Parse(page))

var lastTime = time.Now()

func produceTime() string {
    lastTime = lastTime.Add(time.Second)
    return lastTime.Format("15:04:05")
}

func postsHandler(w http.ResponseWriter, r *http.Request) {
    // Put up some random data for demonstration:
    data := map[string]interface{}{"posts": []Post{
        {User: "Bob", Time: produceTime(), Text: "The weather is nice."},
        {User: "Alice", Time: produceTime(), Text: "It's raining."},
    }}
    var err error
    switch r.URL.Path {
    case "/posts/":
        err = t.Execute(w, data)
    case "/posts/more":
        err = t.ExecuteTemplate(w, "batch", data)
    }
    if err != nil {
        log.Printf("Template execution error: %v", err)
    }
}

produceTime() just produces monotonic increasing timestamp strings, so the output will look like something sensible.

And the main() function to register the handler and start the server:

func main() {
    http.HandleFunc("/posts/", postsHandler)
    panic(http.ListenAndServe(":8080", nil))
}

And that's about it. It's a working application. Entering http://localhost:8080/posts/ in a browser, you'll see:

Posts

09:42:29 Bob: The weather is nice.
09:42:30 Alice: It's raining.
Load more

Pressing the Load more button, the content in the browser will be refreshed dynamically, without page reload. The new content:

Posts

09:42:29 Bob: The weather is nice.
09:42:30 Alice: It's raining.
09:42:31 Bob: The weather is nice.
09:42:32 Alice: It's raining.
Load more

Pressing it again:

Posts

09:42:29 Bob: The weather is nice.
09:42:30 Alice: It's raining.
09:42:31 Bob: The weather is nice.
09:42:32 Alice: It's raining.
09:42:33 Bob: The weather is nice.
09:42:34 Alice: It's raining.
Load more

这篇关于使用模板在Golang中创建加载更多按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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