node.js - 如何将数据库查询从模型传递到 Express.js 中的控制器
问题描述
我有一个product.js
执行此操作的模型文件:
const mssql = require('mssql/msnodesqlv8');
module.exports.rsProducts = function () { // update1: removed params req,res,next
global.MYDB.connect(function (error) { // MYDB is a mssql-server database setup in app.js as a global variable
if (error) {
console.log(error);
return;
}
global.MYDB.request().query('SELECT Top(10) * FROM [dbo].[Product]', function (err, result) {
console.log(result); // this works and i see the database recordset in the console
return(result); // this does not seem to do anything (see below)
});
});
我有一个名为的控制器文件index.js
,它像这样调用模型:
var router = require('express').Router();
const mssql = require('mssql/msnodesqlv8');
const Offer = require('../models/product');
Offer.rsProducts(); // the console.log(result) line in the model file logs the recordset to the console
console.log(Offer.rsProducts()); // this log does not log anything which means no result is being returned from the model file to this controller
我的问题是为什么模型中的return(result)
行product.js
没有向我的控制器返回任何内容?最终我希望控制器呈现这样的视图文件:
router.get('/', function(req, res, next) {
res.render('index', { pagetitle: 'Product Name', data: Offer.rsProducts() });
});
以上永远不会奏效,因为没有任何东西来自Offers.rsProduct()
.
更新 1 我需要一个可扩展的答案,以便控制器可以根据需要从尽可能多的模型调用尽可能多的数据库函数。该网站的主页需要来自大约 4 种不同模型的数据库数据。真的,最终结果(我在脑海中想象)是控制器会做这样的事情(伪代码):
var router = require('express').Router();
const Offer = require('../models/product');
const Story = require('../models/story');
const QandA = require('../models/qanda');
const Job = require('../models/job');
router.get('/', function(req, res, next) {
res.render('index', {
pageTitle: 'Homepage',
offerData: Offer.rsProducts(), //calls Offer's rsProducts function to get the data
storyData: Story.rsStories(), // calls Story's rsStories function to get the data
qandaData: QandA.rsQandAs(), // calls QandA's rsQandAs function to get the data
jobData: Job.rsJobs() // calls Job's rsJobs function to get the data
});
});
解决方案
那里需要解释的东西太多了。
如您所见,所有“I/O”函数(例如,连接到数据库、查询到 db ...)都有一个参数function (err, result) {...
(如function (error)
...),并且作为您的问题“为什么他们不直接返回结果把它包装成一个函数?”。
使用 Javascript,函数就是Callback
函数,JS 不像“正常”的程序语言那样工作。
一个针对您的情况的修补程序,我不知道您为什么将rsProduct
函数定义req, res, next
为参数,但这对我的方式有好处 - 使 rsProduct
成为“中间件”函数:
const mssql = require('mssql/msnodesqlv8');
module.exports.rsProduct = function (req, res, next) {
global.MYDB.connect(function (error) { // MYDB is a mssql-server database setup in app.js as a global variable
if (error) {
console.log(error);
return next(error); // call next with a error to stop flow and throw a error to express app
}
global.MYDB.request().query('SELECT Top(1) * FROM [dbo].[Prodcut]', function (err, result) {
console.log(result); // this works and i see the database recordset in the console
// !!! Assign the result to a new field of req object
req.products = result; // maybe what you need is req.products = result.recordset;
next(); // continue to your function to render view
});
})
}
然后在你的路由器中,
var router = require('express').Router();
const mssql = require('mssql/msnodesqlv8');
const Offer = require('../models/product');
// Offer.rsProduct(); // the console.log(result) line in the model file logs the recordset to the console
// console.log(Offer.rsProduct()); // this log does not log anything which means no result is being returned from the model file to this controller
router.get('/', Offer.rsProduct, function (req, res, next) { // Offer.rsProduct instead of Offer.rsProduct()
res.render('index', { pagetitle: 'Product Name', data: req.products }); // get back products list
});
推荐阅读
- r - 是否可以在 R 中操纵方程以找到方程特定主题的表达式?
- sql-server - 实体框架查询永远不会返回
- c# - 在 sqlite 中附加多个数据库
- python-3.x - Python:我应该如何正确循环我的函数?
- nix - 以下 cmdline 参数的最短 `shell.nix` 等效项是什么?
- visual-studio - 在 Visual Studio 2019 .net Core 2.1 中,如何将 .net Framework 程序集添加到项目中
- r - R:过滤时使用包含函数
- c++ - thread_local 变量在线程内不一致
- android - 清除特定通知
- asp.net-mvc - 路由区域后HelpPage Dont find View