我正在创建一个Web应用程序,当用户搜索特定成分时,它会返回食谱。我正在使用edamam API,并决定使用分页,这样当用户点击“加载更多”按钮时,我就可以加载相对于用户搜索的更多食谱。请注意,edamam一次会返回20个食谱。这是来自edamam关于分页工作原理的文档:
配方搜索API中分页的工作方式与版本1相比发生了重大变化。不再支持from和to参数。相反,响应将在_links. next. href中包含下一个请求的预构造URL。如果此路径不存在,则这是最后一页,并且没有更多结果。
我在很大程度上实现了这个功能,但是,我的html中有一部分使用了ejs if语句,这导致了一些问题(“loadrecipes.js”中的问题)。
我的问题有两个方面:
1.如何解决if语句的问题?
1.在使用AJAX请求时,有没有更好的方法来更新ejs?
代码. Git hub repo is here,方便查看
我有三个文件:
- index.js -服务器端代码
1.使用ejs模板的html - 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();
}
}
});
}
})
我一直在浏览有关堆栈溢出的文档和其他类似的问题,但没有找到对这个问题有帮助的东西。任何帮助将不胜感激!
1条答案
按热度按时间p4tfgftt1#
经过大量的试验和错误和阅读各种文档,我解决了我的问题,创建一个全局变量来保存需要更新+追加的饮食标签html/ejs。我在loadrecipes.js的recipeCard变量中取出if语句。并将if语句的参数赋给diet标签变量。然后,我在食谱卡更新中引用了饮食标签变量。我相信有一个更好的解决方案,但这是我想出的工作。