使用handlebars,如何在不刷新整个页面的情况下更新UI的express.js。

4

这是我第一次使用express.jsHandlebars,需要自动完成此字段:<input type="text" id="myInput" autocomplete="on" placeholder="在此搜索...">。当每个人输入文本时,我需要进行POST和GET请求,而不刷新页面内容。问题是,当我执行GET请求时,Handlebars会刷新整个页面。这是我使用的命令:

res.render('home',{ items:typeOfCategory}); 

以下是hbs的结构:

{{#if items}}
<ul>
{{#each items}} 
<li>{{this.title}}</li>   

{{/each}}
</ul>
{{/if}}

我的问题是:如何避免整个页面的刷新? 谢谢。

使用AJAX避免页面刷新。 - vibhor1997a
@vibhor1997a 这是避免刷新的唯一方法吗? - nani
是的,您可以从客户端发送 AJAX GET 请求,服务器将在响应中发送自动完成数据。 - vibhor1997a
2个回答

4
我曾经在另一个问题中读到类似的内容(链接)。基于这篇教程,我找到了解决所有问题的答案。 此教程讲解如何使用PJAX库来管理客户端和服务器端。 只需3行代码即可实现无需重新加载页面的高速导航。

  1. jQuery-pjax页面安装客户端库
  2. 在发送请求的html页面中添加:<a href='/yourLink' data-pjax='main'>YourLink</a>

其中,main是包含您更改内容的div。在我的情况下是:

 <div id="main" class="main">                    
       {{{body}}}                    
 </div>
  1. In your.js file add $('a[data-pjax]').pjax(); This command 'simply call the pjax extension on every element that contains the data attribute ‘data-pjax’'

  2. Install inside express the depency with the command: npm install --save express-pjax

  3. Set your server:

    var app = express();
    var pjax = require('express-pjax');
    
    ...
    
    app.use(pjax())
    

  1. 替换普通渲染:

res.render('index', {title: "Index"});

改为:

res.renderPjax('index', {title: "Index"});

更新 或者您可以获得相同的结果。请注意,项目结构如下:

views
  |-> partials
  |      |-> addtest.hbs
  |
  |-> index.hbs

例如,假设在您的index.hbs文件中有一个带有不同项目的侧边栏,可以用以下方式描述:
<li>
    <a href="#testDB" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle">
   <img src="../img/database-data.svg" class="svg icon">Test</a>
    <ul class="collapse list-unstyled select-specific" id="testDB">
        <li value="addTest" class=" ">
            <a href="#" id="add-new-test">Add Test</a>
        </li>
         ....
         ....
    </ul>
 </li>

在partials目录中,您有一个简单的表单。现在要管理表单,需要执行两个操作:
  1. 服务器端:为了在不刷新页面的情况下从一个部分切换到另一个部分,您需要指定:

    router.get('/addtest', function (req, res) { res.status(200); res.header("Content-Type", "text/html"); res.render('partials/addtest', {title: "Add Test"}); });

  2. 客户端:在您的客户端文件中,您需要添加一个简单的get请求:

    $('#add-new-test').click(function (event) { $.get('/addtest').then(function (data) { $('#main').html(data); }); });

这样,当您使用相同地址(即在此情况下为 /addtest)进行get请求时,客户端会将一部分代码添加到您的视图中而无需刷新全部内容。 注意:请记住,如果您的部分需要某个file.js文件,请使用以下命令加载该文件:
<script>
var url = "/scripts/script.js";
$.getScript(url);
</script>

这是用于避免:"在主线程上使用同步XMLHttpRequest已弃用...",因为该调用是异步的。更多信息请参见此处


Antonio,你真是个冠军!我用另一种方式使用原生JS和fetch。在onclick异步函数中的客户端脚本:let connection = await fetch(invoice/addcart/${productCodeNumber}); let response = await connection.text(); const invoice = document.getElementById('invoice'); invoice.innerHTML = response; 所以基本上在客户端使用fetch去到你的路由并获取html作为响应文本,然后将其放入ID.innerHTML中。在服务器端,我使用了部分文件并且没有加载布局。与Antonio相同,但res.render部分是layout:false标志。 - Nhon Ha

0

这里的问题是每次都让浏览器请求一个新资源。这会触发你的模板并且每次提供全新的页面。

你需要创建一个返回 JSON 的 express 端点,然后使用类似 AJAX(在 jQuery 中找到)或类似库发送请求到该端点。这样,你就可以向 Web 服务器发出调用,express 可以以 JSON 格式返回一些数据(res.json({})),然后你的前端可以解释该响应并决定如何在 DOM 上显示它。

这种部分更新是你开始需要前端 JS 和返回 JSON 的编程端点的地方。这通常是一些大型前端框架(如 Vuejs 和 Angular)蓬勃发展的地方,但如果你对这种事情还不熟悉,我建议使用 jQuery 向服务器发出 HTTP 调用,并将 JSON 返回到前端。


这个任务的要求是必须使用Express进行HTTP请求,那么我可以使用Express和Ajax吗? - nani
@nani,你的 Express 控制器函数不需要调用 res.render,那只是一种返回响应的方式。你可以使用 res.json(object),其中 object 是你想要传回的数据。它会将其通过 HTTP 发送回 AJAX 函数。然后可以在前端使用这些数据。因此,你可以继续使用 Express 作为 API 的后端。参见文档 - http://expressjs.com/en/4x/api.html#res.json - Elliot Blackburn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接