使用 AJAX 请求更新 ejs 模板

问题描述 投票:0回答:1
我正在创建一个网络应用程序,当用户搜索特定成分时,该应用程序会返回食谱。我正在使用 edamam api 并决定使用分页,以便当用户单击“加载更多”按钮时,我可以加载与用户搜索相关的更多食谱。请注意,edamam 将一次返回 20 个食谱。 这是来自 edamam 关于其分页工作原理的文档:

菜谱搜索 API 中分页的工作方式与版本 1 相比发生了显着变化。不再支持参数 from 和 to。相反,响应将在 _links.next.href 中包含下一个请求的预构建 URL。如果此路径不存在,则这是最后一页,并且没有更多结果。

我基本上可以使用此功能,但是,我的 html 的一部分使用了 ejs if 语句,导致了一些问题(“loadrecipes.js”中的问题)。

我的问题有两个:

    如何解决 if 语句的问题?
  1. 使用 AJAX 请求时是否有更好的方法来更新 ejs?

代码。 Git hub 存储库在这里 更方便查看

我有3个文件:

    index.js - 服务器端代码
  1. index.ejs - 带有 ejs 模板的 html
  2. loadrecipes.js - 客户端代码

index.js

import express from "express"; import axios from "axios"; import bodyParser from "body-parser"; import 'dotenv/config'; const app = express(); const port = 3000; const API_URL = "https://api.edamam.com/api/recipes/v2?type=public"; const myId = process.env.ID; const myAPIKey = process.env.API_KEY; app.use(bodyParser.urlencoded({ extended: true })); app.use(express.static("public")); let nextPageUrl = null; app.get("/", (req, res) => { res.render("index.ejs"); }) app.post("/search", async (req, res) => { const inputText = req.body.ingrediants; try{ const requestUrl = nextPageUrl || API_URL; const response = await axios.get(requestUrl, { params: { q: inputText, app_id: myId, app_key: myAPIKey } }); const result = response.data; //store next page url for pagination if(result._links.next.href){ nextPageUrl = result._links.next.href; } else{ nextPageUrl = null; //no more pages/recipes given the user search } res.render("index.ejs", { recipes: result, userInput: inputText, nextPageUrl: nextPageUrl }); }catch(error){ res.render("index.ejs", { content: "Looks like there's an issue: " + error.message }); } }) app.listen(port, () => { console.log(`Server listening on port ${port}.`); })

index.ejs

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Cook Your Kitchen</title> <link rel="stylesheet" type="text/css" href="styles/main.css"> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous"> </head> <body> <div class="container"> <div class="px-4 py-5 my-4 text-center"> <h1 class="display-5 fw-bold text-body-emphasis">Cook Your Kitchen</h1> <div class="col-lg-6 mx-auto"> <p class="lead mb-4">Have some random ingrediants in your kitchen? <br> Those veggies about to go bad?? <br> Enter the ingrediants you want to use and get recipe suggestions! </p> <form action="/search" method="post"> <div class="d-grid gap-2 d-sm-flex justify-content-sm-center"> <input type="text" id="search" name="ingrediants" class="form-control" placeholder="Chicken, beans, tomato,..." aria-label="Recipient's username" aria-describedby="button-addon2"> <button class="btn btn-outline-secondary" type="submit" value="Submit" id="button-addon2">Get a recipe</button> </div> </form> </div> </div> </div> <% if(locals.recipes){ %> <div class="container px-4 py-5" id="custom-cards"> <h2>You searched for: <%= userInput %> </h2> <div id="recipe-list" class="row row-cols-1 row-cols-lg-3 align-items-stretch g-4 py-5"> <% recipes.hits.forEach(recipe=> { %> <div class="col" onclick="location.href='<%= recipe.recipe.url %>';"> <div class="card card-cover h-100 overflow-hidden text-bg-dark rounded-4" style="background-image: url('<%= recipe.recipe.image %>');"> <div class="d-flex flex-column h-100 p-5 pb-3 text-white text-shadow-1 text-bg"> <h3 class="mt-5 mb-4 display-6 lh-1 fw-bold"> <%= recipe.recipe.label %> </h3> <ul class="d-flex list-unstyled mt-auto"> <% if (recipe.recipe.dietLabels.length > 0) { %> <li class="badge text-bg-dark rounded-pill px-2"> <small> <%= recipe.recipe.dietLabels[0]%> </small> </li> <%} %> <li class="badge text-bg-dark rounded-pill mx-2 px-2"> <small> <%= recipe.recipe.healthLabels[0] %> </small> </li> <li class="badge text-bg-dark rounded-pill px-2"> <small> <%= recipe.recipe.healthLabels[1] %> </small> </li> </ul> </div> </div> </div> <% })} %> </div> </div> <% if (locals.nextPageUrl){ %> <div class="text-center mb-4"> <button type="button" class="btn btn-light" id="loadMoreButton" data-next-page="<%= nextPageUrl %>">Load More</button> </div> <% } %> <script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script> <script src="loadrecipes.js"></script> </body> </html>
这是我正在尝试更新的index.ejs中的部分(红色框)

enter image description here

loadrecipes.js

const nextPageUrl = $("#loadMoreButton").data("next-page"); $("#loadMoreButton").on("click", (event) => { event.preventDefault(); event.stopPropagation(); //using ajax to load more recipes if (nextPageUrl) { $.ajax({ method: "GET", url: nextPageUrl, success: (result) => { // Append result to the existing recipes // and update the nextPageUrl data attribute if there's a next page. const moreRecipes = result.hits; if(moreRecipes.length > 0){ moreRecipes.forEach((recipe) => { //copying card html/ejs from index.ejs and replacing ejs tags for each additionally retrieved recipe const recipeCard = ` <div class="col" onclick="location.href='${recipe.recipe.url}';"> <div class="card card-cover h-100 overflow-hidden text-bg-dark rounded-4" style="background-image: url('${recipe.recipe.image}');"> <div class="d-flex flex-column h-100 p-5 pb-3 text-white text-shadow-1 text-bg"> <h3 class="mt-5 mb-4 display-6 lh-1 fw-bold"> ${recipe.recipe.label} </h3> <ul class="d-flex list-unstyled mt-auto"> <% if (${recipe.recipe.dietLabels.length} > 0) { %> <li class="badge text-bg-dark rounded-pill px-2"> <small> ${recipe.recipe.dietLabels[0]} </small> </li> <%} %> <li class="badge text-bg-dark rounded-pill mx-2 px-2"> <small> ${recipe.recipe.healthLabels[0]} </small> </li> <li class="badge text-bg-dark rounded-pill px-2"> <small> ${recipe.recipe.healthLabels[0]} </small> </li> </ul> </div> </div> </div> `; // Append the new recipe card to the recipe list div $("#recipe-list").append(recipeCard); }); // Update the nextPageUrl data attribute $("#loadMoreButton").data("next-page", result._links.next.href); } else { // If there are no more recipes, hide the "Load More" button $("#loadMoreButton").hide(); } } }); } })
我一直在查看堆栈溢出上发布的文档和其他类似问题,但没有发现对这个确切问题有帮助的内容。任何帮助将不胜感激!

javascript node.js ajax ejs edamam-api
1个回答
0
投票
经过大量试验和错误并阅读各种文档后,我通过创建一个全局变量来保存需要更新+附加的饮食标签 html/ejs 解决了我的问题。我在 loadrecipes.js 中的recipeCard 变量中提取了 if 语句。并将 if 语句的参数分配给饮食标签变量。然后我在食谱卡更新中引用了饮食标签变量。我相信可能有更好的解决方案,但这就是我提出的有效解决方案。

const nextPageUrl = $("#loadMoreButton").data("next-page"); $("#loadMoreButton").on("click", (event) => { event.preventDefault(); event.stopPropagation(); let dietLabel = ""; //using ajax to load more recipes if (nextPageUrl) { $.ajax({ method: "GET", url: nextPageUrl, success: (result) => { // Append result to the existing recipes // and update the nextPageUrl data attribute if there's a next page. const moreRecipes = result.hits; if(moreRecipes.length > 0){ moreRecipes.forEach((recipe) => { if(recipe.recipe.dietLabels.length > 0){ dietLabel = ` <li class="badge text-bg-dark rounded-pill px-2"> <small> ${recipe.recipe.dietLabels[0]} </small> </li> `; } //copying card html/ejs from index.ejs and replacing ejs tags for each additionally retrieved recipe const recipeCard = ` <div class="col" onclick="location.href='${recipe.recipe.url}';"> <div class="card card-cover h-100 overflow-hidden text-bg-dark rounded-4" style="background-image: url('${recipe.recipe.image}');"> <div class="d-flex flex-column h-100 p-5 pb-3 text-white text-shadow-1 text-bg"> <h3 class="mt-5 mb-4 display-6 lh-1 fw-bold"> ${recipe.recipe.label} </h3> <ul class="d-flex list-unstyled mt-auto"> ${dietLabel} <li class="badge text-bg-dark rounded-pill mx-2 px-2"> <small> ${recipe.recipe.healthLabels[0]} </small> </li> <li class="badge text-bg-dark rounded-pill px-2"> <small> ${recipe.recipe.healthLabels[1]} </small> </li> </ul> </div> </div> </div> `; // Append the new recipe card to the recipe list div $("#recipe-list").append(recipeCard); }); // Update the nextPageUrl data attribute $("#loadMoreButton").data("next-page", result._links.next.href); } else { // If there are no more recipes, hide the "Load More" button $("#loadMoreButton").hide(); } } }); } })
    
© www.soinside.com 2019 - 2024. All rights reserved.