Мое приложение написано на expressjs, handlebars, mongoose / mongodb, и я не могу понять, как мне отсортировать массив до того, как руль напечатает его.
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.log('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 (модель mongoose)
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.log(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
, но я хочу отсортировать его на стороне, а затем вывести на экран.