Je travaille sur une application de blog (cliquez sur le lien pour voir le GitHub repo) avec Express , EJS et MongoDB.
J'ai fait un simple pager pour les messages.
Dans les messages contrôleur j'ai:
exports.getPosts = async (req, res, next) => {
const posts = await Post.find({}, (err, posts) => {
const perPage = 10;
const currPage = req.query.page ? parseInt(req.query.page) : 1;
const postsCount = posts.length;
const pageCount = Math.ceil(postsCount / perPage);
const pageDecrement = currPage > 1 ? 1 : 0;
const pageIncrement = currPage < pageCount ? 1 : 0;
if (err) {
console.log("Error: ", err);
} else {
res.render("default/index", {
moment: moment,
layout: "default/layout",
website_name: "MEAN Blog",
page_heading: "XPress News",
page_subheading: "A MEAN Stack Blogging Application",
currPage: currPage,
pageDecrement: pageDecrement,
pageIncrement: pageIncrement,
posts: posts,
});
}
})
.sort({ created_at: -1 })
.populate("category")
.limit(perPage)
.skip((currPage - 1) * perPage);
};
Le téléavertisseur dans la vue:
<% if (posts) {%>
<div class="clearfix d-flex justify-content-center">
<div class="px-1">
<a class="btn btn-primary <%= pageDecrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage - pageDecrement %>">← Newer Posts</a>
</div>
<div class="px-1">
<a class="btn btn-primary <%= pageIncrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage + pageIncrement %>">Older Posts →</a>
</div>
</div>
<% } %>
La ligne .limit(perPage)
du contrôleur donne l'erreur perPage is not defined
Dans la console (Git bash).
Clairement, je peux déplacer ces 2 lignes au-dessus de const posts
const perPage = 5;
const currPage = req.query.page ? parseInt(req.query.page) : 1;
mais je peux pas faire la même chose avec const postsCount = posts.length;
(dont j'ai également besoin dans la vue).
J'essaie de rendre l'extrait de code concernant la pagination réutilisable (comme un plugin, si possible), car j'ai besoin de paginer pour les messages filtrés par catégorie, ainsi que la liste des articles dans la section admin de l'application.
Qu'est-ce que je fais mal?
Comme expliqué par d'autres commentaires. Cela pourrait simplement être un problème de portée.
exports.getPosts = async (req, res, next) => {
const perPage = 10; // enable you to use perPage inside getPosts()
let postsCount = 0; // let, to enable you to use/reassigned postsCount inside getPosts()
const posts = await Post.find({}, (err, posts) => {
// ...
postsCount = posts.length; // updates the variable with the correct count
// ...
if (err) {
console.log("Error: ", err);
} else {
res.render("default/index", {
//...
posts: posts,
postsCount: posts.length, // for explicit postsCount in the view
});
}
});
// ..
pour votre problème avec postsCount dans la vue, puisque vous avez déjà posts
dans votre vue
<% if (posts) {%>
...
<% } %>
Je pense que vous pouvez simplement utiliser posts.length
ou postsCounts
dans la vue comme la façon dont vous utilisez les autres (par exemple, pageIncrement, currPage, pageIncrement);
Peut-être que si vous vérifiez ce composant, vous pouvez résoudre votre problème en voyant comment cela fonctionne
$ npm install mongoose-paginate
/**
* querying for `all` {} items in `MyModel`
* paginating by second page, 10 items per page (10 results, page 2)
**/
MyModel.paginate({}, 2, 10, function(error, pageCount, paginatedResults) {
if (error) {
console.error(error);
} else {
console.log('Pages:', pageCount);
console.log(paginatedResults);
}
}
Comme je l'ai découvert récemment postsCount = posts.length
Compte les messages après ils sont limités par .skip((currPage - 1) * perPage)
, donc la variable pageIncrement
"équation" se transforme en:
let pageIncrement = postsCount >= perPage ? 1 : 0;
Alors je reçois, dans le contrôleur:
exports.getPosts = async (req, res, next) => {
const perPage = 5;
const currPage = req.query.page ? parseInt(req.query.page) : 1;
let postsCount = 0;
const posts = await Post.find({}, (err, posts) => {
postsCount = posts.length;
let pageDecrement = currPage > 1 ? 1 : 0;
let pageIncrement = postsCount >= perPage ? 1 : 0;
if (err) {
console.log('Error: ', err);
} else {
res.render('default/index', {
moment: moment,
layout: 'default/layout',
website_name: 'MEAN Blog',
page_heading: 'XPress News',
page_subheading: 'A MEAN Stack Blogging Application',
currPage: currPage,
posts: posts,
pageDecrement: pageDecrement,
pageIncrement: pageIncrement
});
}
})
.sort({
created_at: -1
})
.populate('category')
.limit(perPage)
.skip((currPage - 1) * perPage);
};
Et dans la vue:
<a class="btn btn-primary <%= pageDecrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage - pageDecrement %>">← Newer Posts</a>
et
<a class="btn btn-primary <%= pageIncrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage + pageIncrement %>">Older Posts →</a>
Cela fonctionne bien à moins qu'il y ait un nombre de messages égal à perPage x N
, Où N est un entier, auquel cas le bouton "Articles plus anciens" devient désactivé une page trop tard.