Mongoose/NodeJS - .EJS 模板中的排序按钮
Mongoose/NodeJS - Sort button in .EJS template
在我的 Mongoose 控制器中,我根据产品的创建日期进行排序:
let products = await Product.find().sort({ 'createdAt': -1 });
我想在 EJS 模板中创建一个按钮,允许用户 select 不同的排序标准(例如价格)。创建按钮本身没问题,但我不知道如何在选项 selected 时访问控制器中的排序功能(例如 if price selected,sort by price),以及我应该把代码放在哪里,在控制器中还是在 EJS 模板中?
我想我应该使用 req.query
,但我不知道如何使用。谢谢
第一部分 - 抽象 Mongoose API 到 JS
Mongoose 允许您分段构建 query
。假设您有一个函数查询 Product
和附加选项对象。
findOptions - 包含过滤器选项(查询的 where
部分)
pagingOptions - 包含 排序+排序、页面和 pageSize。
这是构建查询所需的全部上下文。
async function getProducts(findOptions, pagingOptions) {
const query = Product.find(findOptions);
if(pagingOptions.sort) {
// Note: This example assumes that paging.sort has the same structure as Monguse sort object.
query.sort(paging.sort);
}
let products = await query.exec();
...
return products;
}
用法:
let products = await getProducts({}, { 'createdAt': -1 });
let products = await getProducts({ 'createdAt': { $gt: Date.now() }}, { '_id': 1 });
您可以使用选项对象来添加或限制很多东西来管理查询上下文
参见:mongoose query doc
第二部分 - 公开 API
现在我们在 server-side 中有一个方法可以仅使用 JS 对象 (JSON
) 查询 Products
,您将需要公开一个 HTTP API因此客户端将能够使用他的查询条件调用服务器。
让我们定义这是我们将发送给客户端以集成的 HTTP API:
POST /products
// 请求正文
{
sort: { FIELD_NAME: ASC|DESC }, // ASC=1, DESC=-1
}
用法:
curl -X POST -H "Content-Type: application/json" --data '{ sort: { "createdAt": "1" } }' http:localhost:3000
注意:您可以扩展 HTTP API 和后端方法选项以进一步扩展功能。
查看以下内容以了解如何通过 express 实现 HTTP 端点
https://expressjs.com/en/guide/routing.html
http://expressjs.com/en/resources/middleware/body-parser.html#bodyparserjsonoptions
第三部分 - 前端集成
现在剩下的就是实现 HTTP 客户端并公开 HTTP API,以便其余的前端模块能够调用后端。
以下是一个简单的 fetch
示例,但您可以使用任何您喜欢的 HTTP 客户端库。
const productsEndpoint = baseUrl + '/products';
async function getProducts(options) {
const response = await fetch(productsEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(options)
});
return response.json();
}
这三个步骤将使您 well-defined API 跨组件及其中的层。
在我的 Mongoose 控制器中,我根据产品的创建日期进行排序:
let products = await Product.find().sort({ 'createdAt': -1 });
我想在 EJS 模板中创建一个按钮,允许用户 select 不同的排序标准(例如价格)。创建按钮本身没问题,但我不知道如何在选项 selected 时访问控制器中的排序功能(例如 if price selected,sort by price),以及我应该把代码放在哪里,在控制器中还是在 EJS 模板中?
我想我应该使用 req.query
,但我不知道如何使用。谢谢
第一部分 - 抽象 Mongoose API 到 JS
Mongoose 允许您分段构建 query
。假设您有一个函数查询 Product
和附加选项对象。
findOptions - 包含过滤器选项(查询的 where
部分)
pagingOptions - 包含 排序+排序、页面和 pageSize。
这是构建查询所需的全部上下文。
async function getProducts(findOptions, pagingOptions) {
const query = Product.find(findOptions);
if(pagingOptions.sort) {
// Note: This example assumes that paging.sort has the same structure as Monguse sort object.
query.sort(paging.sort);
}
let products = await query.exec();
...
return products;
}
用法:
let products = await getProducts({}, { 'createdAt': -1 });
let products = await getProducts({ 'createdAt': { $gt: Date.now() }}, { '_id': 1 });
您可以使用选项对象来添加或限制很多东西来管理查询上下文 参见:mongoose query doc
第二部分 - 公开 API
现在我们在 server-side 中有一个方法可以仅使用 JS 对象 (JSON
) 查询 Products
,您将需要公开一个 HTTP API因此客户端将能够使用他的查询条件调用服务器。
让我们定义这是我们将发送给客户端以集成的 HTTP API:
POST /products
// 请求正文
{
sort: { FIELD_NAME: ASC|DESC }, // ASC=1, DESC=-1
}
用法:
curl -X POST -H "Content-Type: application/json" --data '{ sort: { "createdAt": "1" } }' http:localhost:3000
注意:您可以扩展 HTTP API 和后端方法选项以进一步扩展功能。
查看以下内容以了解如何通过 express 实现 HTTP 端点 https://expressjs.com/en/guide/routing.html http://expressjs.com/en/resources/middleware/body-parser.html#bodyparserjsonoptions
第三部分 - 前端集成
现在剩下的就是实现 HTTP 客户端并公开 HTTP API,以便其余的前端模块能够调用后端。
以下是一个简单的 fetch
示例,但您可以使用任何您喜欢的 HTTP 客户端库。
const productsEndpoint = baseUrl + '/products';
async function getProducts(options) {
const response = await fetch(productsEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(options)
});
return response.json();
}
这三个步骤将使您 well-defined API 跨组件及其中的层。