在 Handlebars 中使用带有按钮的 Javascript 函数

Posted

技术标签:

【中文标题】在 Handlebars 中使用带有按钮的 Javascript 函数【英文标题】:Using Javascript functions with a button in Handlebars 【发布时间】:2022-01-13 23:08:06 【问题描述】:

我有一个具有以下结构的车把项目:

Project
 |
 +-- server.js
 +-- package.json
 +-- package-lock.json
 |    
 +-- public
 |  |  
 |  |-- css
 |      |
 |      + -- style.css
 |
 +-- views
 |  |  
 |  |-- layouts
 |  |   |
 |  |   + -- main.handlebars
 |  +-- index.handlebars

在我的 server.js 文件中,我创建了要在 localhost:3000 上运行的应用程序,并在 / 提供 index.handlebars。我了解如何从 api 中获取信息,所以只是为了学习如何在车把应用程序中导航显示来自 API 的数据,我创建了一个 GetInsult(); 函数来从我在网上找到的 API 中检索随机侮辱(纯粹用于学习目的)。我用函数抓取数据,然后将数据传递给res.render()函数。你可以在我的server.js 文件中看到它是如何工作的:

//import modules
import dotenv from 'dotenv';
dotenv.config();

import http from 'http';
import path from 'path';
import  dirname  from 'path';
import express from 'express';
import  engine  from 'express-handlebars';
import axios from 'axios';


//other variables
const port = process.env.PORT;
const hostname = process.env.HOSTNAME;
const __dirname = path.resolve();

//store data in variable
var insult = await GetInsult();


const app = express();

//Create http server to run and listen on localhost:3000
var server = http.createServer(app).listen(port, hostname, () => 
    console.log(`Server is running at http://$hostname:$port`);
)

app.engine('handlebars', engine());
app.set('view engine', 'handlebars')
app.set('views', './views')

//Use Static Files
app.use('/public', express.static(__dirname + '/public'));
app.use('/css', express.static(path.join(__dirname, 'node_modules/bootstrap/dist/css')));
app.use('/js', express.static(path.join(__dirname, 'node_modules/bootstrap/dist/js')));
app.use('/js', express.static(path.join(__dirname, 'node_modules/jquery')));

app.get('/', (req, res) => 
    res.render('index' , insult)
);



export async function GetInsult() 
    var response = await axios('https://insult.mattbas.org/api/insult')
    var data = response.data
    return data


console.log(insult)

然后在我的index.handlebars 文件中,我可以像这样成功地显示侮辱:

<main>
    <div style="text-align: center;">
        <h1 id="insult">insult</h1>
        <button id="insult-button" class="btn btn-dark">Get New Insult</button>
    </div>
</main>

我无法弄清楚如何将GetInsult(); 功能添加到&lt;h1&gt;insult&lt;/h1&gt; 标签下方的按钮中。我尝试了很多方法,感觉好像我错过了一些简单的东西。我希望按钮执行GetInsult(); 函数并显示从API 检索到的新侮辱。我不确定我是否需要将函数存放在其他地方并从另一个文件中调用它,或者是否甚至可以使用异步函数。任何指导将不胜感激。谢谢!

【问题讨论】:

【参考方案1】:

我希望按钮执行 GetInsult();函数并显示从 API 检索到的新侮辱。

基本步骤如下:

1 - 创建一些客户端 javascript,在浏览器中进行 Ajax 调用(使用 fetch() 接口),向服务器上的新路由发出 GET 请求。如果您想区分返回 JSON 的路由和用于浏览器的路由,您可以将该路由设置为 /api/insult

2 - 在您的服务器上为/api/insult 实现一个路由,如下所示:

app.get("/api/insult", async (req, res) => 
    try 
        let insult = await GetInsult();
        res.json(insult);
     catch(e) 
        console.log(e);
        res.sendStatus(500);
    
);

3 - 然后,在您的客户端代码中获取侮辱,从 fetch() 调用中获取结果并将其插入到您当前的网页中以替换当前的侮辱。

您的客户端代码可能如下所示:

document.getElementById("insult-button").addEventListener("click", async (e) => 
    try 
        let response = await fetch("/api/insult");
        let data = await response.json();
        document.getElementById("insult").innerhtml = data.insult;
     catch(e) 
        console.log(e);
        alert("Request for new insult failed.")
    
);

确保在您的index.handlebars 模板中的&lt;script&gt; 标记中将此客户端代码放在insult-button 之后。


工作原理总结:

因此,每次单击该按钮时,它都会向您的服务器发出一个新的 API 请求。您的服务器将收到新的侮辱,并在 API 响应中返回。然后您的客户端代码将获得响应,将其解析为 JSON,然后将侮辱插入到先前侮辱所在的网页中。

【讨论】:

太棒了,感谢您的回答,这有效。我最初试图将 GetInsult() 函数放在另一个文件中,但有了这些信息,我相信我可以从这里开始工作。

以上是关于在 Handlebars 中使用带有按钮的 Javascript 函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在 EmberJS 验收测试中调用输入和按钮?

Handlebars.Compile() 函数中的 C# 车把错误

服务器和客户端上带有 Handlebars.js 的 Node.js

Handlebars 和 Node.js:#if !user 然后显示登录按钮

Handlebars:有没有办法输出作为数组一部分的完整对象(带有“每个”)?

错误:Handlebars.js 中缺少帮助程序