更新现有列表,而无需重新加载整个页面

时间:2019-08-06 21:01:23

标签: javascript node.js sockets

我正在寻找用API调用的新结果列表更新API调用的当前结果列表的最佳方法。

我正在向新闻API发出API请求,并在首次加载时将它们加载到索引页面中:

app.get("/", function (req, res) {

    request("https://newsapi.org/v2/top-headlines?q=" + initialQ + "&category=sports&pageSize=10&page=" + page + "&sortBy=relevance&apiKey=" + apiKey, function (error, response, body) {

        if (!error && response.statusCode == 200) {

            let data = JSON.parse(body);

            totalResults = data.totalResults;

            console.log(totalResults)

            let articles = scripts.articlesArr(data);

            let filteredArticles = scripts.filteredArr(articles);

            res.render("index", { filtered: filteredArticles });

        } else {
            res.redirect("/");
            console.log(response.body);
        }
    });
});

然后,用户将切换两个按钮以获得更多结果,或者返回上一页:

app.post("/", function (req, res) {
    let inputValue = req.body.page;
    let pages = Math.ceil(totalResults / 10)

    page = scripts.iteratePages(inputValue, page, pages);

    request("https://newsapi.org/v2/top-headlines?q=" + initialQ + "&category=sports&pageSize=10&page=" + page + "&sortBy=relevance&apiKey=" + apiKey, function (error, response, body) {

        if (!error && response.statusCode == 200) {

            let data = JSON.parse(body);

            let articles = scripts.articlesArr(data);

            let filteredArticles = scripts.filteredArr(articles);

            res.render("index", { filtered: filteredArticles });

        } else {
            res.redirect("/");
            console.log(response.body);
        }
    });
});

我知道Socket io,但是我想知道是否还有其他方法或方法来实现?据我了解,我可以通过前端来更新前端内容-但根据目前的设置,我更希望从后端进行更新

EJS代码:

    <div id="container">
        <% for(var i=0; i < filtered.length; i++) { %>
            <ul>
                <li><%= filtered[i].title %></li>
                <li><%= filtered[i].date %></li>
                <li><img src="<%= filtered[i].image%>" /></li>
                <li><%=filtered[i].description%></li>
                <li><%= filtered[i].link %></li>
            </ul>
        <% } %>
    </div>
    <form action="/" method="POST">
        <ul>
            <li>
                <button type="submit" name="page" value="next">Get more results</button>
                <button type="submit" name="page" value="prev">Go back a page</button>
            </li>
        </ul>
    </form>

1 个答案:

答案 0 :(得分:1)

对于双向通信,我们可以使用WebSockets(带有Socket.IO之类的库),对于单向服务器到客户端,我们可以使用EventSource,对于单向客户端到服务器,我们可以使用良好的ol 'HTTP,通过浏览器API中的fetchXMLHttpRequest(这被称为AJAX,尽管我认为现在大多数开发人员只是说“客户端调用服务器”)。对于99%的用例,我们想要的是通过HTTP的客户端到服务器。如果我理解正确,那么您希望用户按下按钮时发生事情。客户端到服务器就是这种情况。

  1. 用户按下按钮
  2. 客户使用/articles调用我们的新API端点fetch,以获取更多文章:const data = await fetch('localhost:8080/articles'); const articles = await data.json()/articles的简化代码看起来像app.get('/articles', (req, res) => request("https://newsapi.org").then(articles => /* do stuff with articles here */res.send(result))。此端点返回json而不是html(我们的/端点返回html)
  3. 我们的服务器调用newsapi。 Newsapi解析了我们的服务器。我们的服务器会回答客户。
  4. 然后,我们需要一些数据绑定/模板,以确保使用新文章更新DOM。这是像React和Angular供应这样的功能库。但是出于学习目的和简化操作,您可以执行articles.forEach(a => {const el = document.createElement('li'); el.innerHtml = a; document.getElementById('articles').appendChild(el)})之类的操作,假设存在一个标签<ul id="articles">...,该标签应显示文章(您可能希望对文章进行更复杂的操作,但是你明白了)
  5. 页面尚未重新加载?

更新:一些代码审查:)

  • 使用模板文字。 "https://newsapi.org/v2/top-headlines?q=" + initialQ + "&category=sports&pageSize=10&page=" + page + "&sortBy=relevance&apiKey=" + apiKey-> https://newsapi.org/v2/top-headlines?q=${initialQ}&category=sports&pageSize=10&page=${page}&sortBy=relevance&apiKey=${apiKey}
  • const胜过let
  • 当行很长时使用新行(许多行以80列为首选最大宽度)
  • 您似乎对每篇文章都进行了一次ul,对文章中的每个属性都进行了一次liul是列表(无序列表),而li是列表项。因此,一个ul应该包含许多li,每个li应该包含一项(在本例中为一篇文章)。您可以阅读有关Web开发here
  • 中语义的更多信息