Мое приложение написано на expressjs, handlebars, mongoose / mongodb, и я не могу услышать, как мне отсортировать свой массив, прежде чем handlebars его напечатает.
app.js (точка входа)
var debug = require('debug');
var express = require('express');
var fs = require('fs');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var exphbs = require('express-handlebars')
...
...
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('hbs', exphbs({ extname: '.hbs', defaultLayout: 'layout' }));
app.set('view engine', 'hbs');
app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: 'gh jewellery',
resave: false,
saveUninitialized: false,
cookie: { secure: false }
}));
app.use(function (req, res, next) {
console.info('middleware was called');
res.locals.session = req.session;
req.session.LoggedIn = false;
next();
});
Выше я объявляю сеанс локальной переменной, поскольку я буду использовать ее в своем представлении макета. Вкратце, он состоит из панели навигации, которая будет содержать значок уведомления, значок имени пользователя и значок сообщения с соответствующими данными. Ниже находится layout.hbs
layout.hbs
<!doctype html>
<html lang = "en">
<head>
...
<title></title>
</head>
<body>
<nav class = "navbar navbar-expand navbar-light bg-light sticky-top">
<a class = "navbar-brand" id = "cus" href = "/" style = "font-size:12px;"></a>
{{#if session.loggedIn}}
<div class = "collapse navbar-collapse" id = "navbarNavDropdown">
<ul class = "navbar-nav ml-auto">
<li class = "nav-item dropdown ">
<a class = "nav-link" href = "#" id = "navbarDropdownMenuLink" role = "button" data-toggle = "dropdown" aria-haspopup = "true" aria-expanded = "false">
<i class = "far fa-bell fa-lg" style = "color:darkblue;"></i><span class = "label label-info"> {{session.user.notification.counter}}</span>
</a>
<div class = "dropdown-menu dropdown-menu-right" aria-labelledby = "navbarDropdownMenuLink">
{{#each session.user.notification.notidata}}
<div class = "dropdown-item" href = "#">
<div>
<h6>{{data.heading}}</h6>
<small>{{data.para}}</small>
<small class = "text-muted">{{notidate}}</small>
<a style = "float:right; font-size:8px;" href = "#" class = "badge badge-secondary">Mark As Read</a>
</div>
</div>
<div class = "dropdown-divider"></div>
{{/each}}
<form action = "/logout" method = "post">
<button class = "btn btn-light btn-block logoutbutton" type = "submit">View All Notifications</button>
</form>
</div>
</li>
<li class = "nav-item dropdown ">
<a class = "nav-link" href = "#" id = "navbarDropdownMenuLink" role = "button" data-toggle = "dropdown" aria-haspopup = "true" aria-expanded = "false">
<i class = "far fa-envelope fa-lg" style = "color:darkblue;"></i><span class = "label label-info"> {{session.user.message.counter}}</span>
</a>
<div class = "dropdown-menu dropdown-menu-right" aria-labelledby = "navbarDropdownMenuLink">
<a class = "dropdown-item" href = "#">
<div>
<h6>Heading</h6>
<small>This is the paragramgh look pretty cool to me if you ask!</small>
</div>
</a>
<div class = "dropdown-divider"></div>
<form action = "/logout" method = "post">
<button class = "btn btn-light btn-block logoutbutton" type = "submit">View All Messages</button>
</form>
</div>
</li>
<li class = "nav-item dropdown ">
<a class = "nav-link " href = "#" id = "navbarDropdownMenuLink" role = "button" data-toggle = "dropdown" aria-haspopup = "true" aria-expanded = "false">
<i class = "fas fa-user-circle fa-lg" style = "color:darkblue;"> {{session.user.username}}</i>
</a>
<div class = "dropdown-menu dropdown-menu-right" aria-labelledby = "navbarDropdownMenuLink">
<a class = "dropdown-item" href = "/profile/{{session.user._id}}">Profile</a>
<div class = "dropdown-divider"></div>
<a class = "dropdown-item" href = "/adreqform">Post an Order</a>
<div class = "dropdown-divider"></div>
<a class = "dropdown-item" href = "/managereq">Manage Order Requests</a>
<div class = "dropdown-divider"></div>
<form action = "/logout" method = "post">
<button class = "btn btn-light btn-block logoutbutton" type = "submit">Logout</button>
</form>
</div>
</li>
</ul>
{{/if}}
{{#unless session.loggedIn}}
<div class = "navbar-text ml-auto">
Hello! <a href = "/signup" style = "color:darkblue">Sign up</a> or <a href = "/login" style = "color:darkblue">Login</a>
</div>
{{/unless}}
</div>
</nav>
<div class = "container-fluid">
<div class = "row">
<div class = "col-md-2">
</div>
<div class = "col-md-7">
{{{body}}}
</div>
<div class = "col-md-3">
<div class = "w-100 ">
<br />
<div class = "card">
<div class = "card-body">
<h5 class = "card-title">Special title treatment</h5>
<hr>
<p class = "card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href = "#" class = "btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
<div class = "w-100">
<br />
<div class = "card">
<div class = "card-body">
<h5 class = "card-title">Special title treatment</h5>
<hr>
<p class = "card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href = "#" class = "btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!--<script>
$(document).ready(function () {
$(".dropdown-toggle").dropdown();
});
</script>-->
</body>
</html>
user.models.js (модель мангуста)
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
username: String,
email: String,
password: String,
company: String,
contact: Number,
country: String,
isLoggedIn: Boolean,
createdOn: { type: Date, default: Date.now },
ads: [{ type: Schema.Types.ObjectId, ref: 'Ad' }],
notification: {
counter: Number,
notidata: [{
notiId: Schema.Types.ObjectId,
notidate: { type: Date, default: Date.now },
data: {
heading: String,
para: String
},
notistatus: {type: Boolean, default: false}
}]
}
});
var User = module.exports = mongoose.model('User', UserSchema);
myroute.js (частичный код, которого достаточно, чтобы объяснить мою проблему)
var user3 = {
username: req.body.username,
email: req.body.email,
password: req.body.password,
country: req.body.country
};
var newuser = new User(user3);
newuser.save(function (err, newuser) {
if (err) {
console.info(err);
}
req.session.user = newuser;
req.session.loggedIn = true;
req.session.save();
Обратите внимание, как я назначаю req.session.user текущему пользователю через
req.session.user = newuser;
Теперь у меня есть проблема, поскольку layout.hbs не попадает в маршрут, когда он вызывается при первом открытии localhost:3000, в какой момент я могу отсортировать массив notidata. По сути, все документы user содержат данные уведомлений в массиве notidata и печатаются в layout.hbs с помощью хелпера #each. Я хочу, чтобы notidata отсортировал по дате, а затем распечатал, но поскольку не существует маршрута, который подвергается ударам, я не знаю, где я могу сделать что-то вроде User.find().sort(notidate: 'desc')..., или, может быть, это даже не то, как это будет сделано? Это session.user, который печатает notidata, я так растерялся.
Поскольку session.user - это то, что печатает notidata в layout.hbs, как мне отсортировать его перед просмотром? Я где-то читал, что могу использовать пользовательский помощник по рулям на интерфейсе, который сначала сортирует, а затем повторяет notidata, но я хочу отсортировать его на стороне, а затем вывести его в представление.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


когда вы создали нового пользователя и сохранили его, он вернет ваш объект пользователя. так что вы можете получить его и манипулировать или изменять в любом порядке:
newuser.save(function (err, newuser) {
if (err) {
console.info(err);
}
//here before returning the whole user object you can sort it:
const notidata = newUser.notification.notidata;
const sortedNotiData = notidata.sort(function(a,b){
return new Date(a.notidate) - new Date(b.notidate);
})
// now sortedNotiDate contain sorted data so:
newuser.nottification.notidata = sortedNotiData;
req.session.user = newuser;
req.session.loggedIn = true;
req.session.save();
Я думаю, что дата пользователя вернется, когда он / она войдет в систему. Есть ли у вас какой-либо маршрут, который указывает на аутентификацию или
/login? там вы можете найти пользователя и вернуть его по своему усмотрению