关于express的视图助手和路由分配 Nodejs 问题探讨
关于express的视图助手和路由分配 Nodejs 问题探讨
我是一个刚开始学习nodejs的新手, 在读完nodejs开发指南的时候感觉nodejs很强大 不过,当真正开始做的时候发现书中的express里面 关于视图助手部分和将路由分出来的功能已经不能用 而且在链接mongodb的时候也是不行.
看了官方文档将里面的内容看了一遍也没发现什么视图助手的部分 搁浅了一阵子,想请教一下用express框架视图助手和路由分出的功能应该怎么做才是?
当然可以。Express 是一个简洁而灵活的 Node.js Web 应用程序框架,提供了一系列强大的功能来帮助创建各种 Web 和移动设备的应用。它主要用于处理 HTTP 请求、路由、模板引擎以及中间件等功能。下面我们将讨论如何使用 Express 实现视图助手(view helpers)和路由分配。
视图助手
视图助手是在视图中频繁使用的辅助函数或变量,可以提高代码的复用性和可维护性。在 Express 中,可以通过自定义中间件或者直接在渲染时传递数据来实现视图助手。
示例代码:
-
安装必要的依赖:
npm install express ejs --save
-
设置视图助手: 在你的应用中,你可以通过
app.locals
或者res.locals
来设置全局或者局部的视图助手。const express = require('express'); const app = express(); // 设置全局视图助手 app.locals.title = 'My App'; app.locals.year = new Date().getFullYear(); // 设置局部视图助手 app.use((req, res, next) => { res.locals.user = req.session.user; next(); }); // 设置视图引擎 app.set('view engine', 'ejs'); // 定义路由 app.get('/', (req, res) => { res.render('index', { message: 'Hello World' }); }); app.listen(3000, () => { console.log('Server is running on port 3000'); });
-
在视图文件中使用助手: 假设你有一个
index.ejs
文件,你可以这样使用这些助手:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title><%= title %></title> </head> <body> <h1><%= message %></h1> <p>© <%= year %> - All rights reserved</p> <% if (user) { %> <p>Welcome, <%= user.name %></p> <% } else { %> <p>Please log in to view this page.</p> <% } %> </body> </html>
路由分配
路由分配是指根据不同的请求路径执行不同的逻辑。Express 提供了简单的方法来定义路由。
示例代码:
const express = require('express');
const app = express();
// 定义路由
app.get('/about', (req, res) => {
res.send('About Page');
});
app.get('/contact', (req, res) => {
res.send('Contact Page');
});
app.get('*', (req, res) => {
res.status(404).send('Page Not Found');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
以上就是关于 Express 的视图助手和路由分配的基本介绍和示例代码。希望这对你有所帮助!
我也在看这本书,这本书写作是在2012年左右,在这几年里express 有了很大的变化,比如 layout 和 partical 都在最新的3.X版里面去掉了。你可以联系这本书的作者 BYVoid 来解答一下。他的博客联系方式是:http://www.byvoid.com/contact
技术永远都是快速发展的
https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x
Migrating from 2.x to 3.x
Removed
res.render()
“status” option (use node’sres.statusCode=
orres.status(code).render(...)
)res.render()
“charset” option (useres.charset=
)res.local(foo, bar)
(useres.locals.foo = bar
orres.locals({ foo: bar })
instead)app.dynamicHelpers()
(use middleware +res.locals
)app.helpers()
(useapp.locals
)- the concept of a “layout” (template engine specific now)
partial()
(template engine specific)res.partial()
- “view options” setting, use
app.locals
- “hints” setting
req.isXMLHttpRequest
(usereq.xhr
)app.error()
(use middleware with (err, req, res, next))req.flash()
(just use sessions:req.session.messages = ['foo']
or similar)- connect-flash can be used as middleware to provide req.flash()
- the
jsonp callback
setting was removed (useres.jsonp()
)
Changed
req.header(field[, defaultValue])
replaced byreq.get(field)
(remains for backwards compatibility)res.header(field[, value])
replaced byres.set(field, value)
/res.get(field)
(remains for backwards compatibility)- renamed
app.register()
toapp.engine()
- template engine compliance from
engine.compile(str, options) => Function
toengine.__express(filename, options, callback)
express.createServer()
is now simplyexpress()
(but remains for BC).- Keep in mind that the return value of
express()
is no longer anhttp.Server
instance. (See the Application function section below for more details)
- Keep in mind that the return value of
View options
The “view options” setting is no longer necessary, app.locals
are the local variables
merged with res.render()
's, so app.locals.pretty = true
is the same as passing res.render(view, { pretty: true })
.
Application function
The return value of express()
is a JavaScript Function
, encapsulating everything
that makes an Express app tick. This means you can easily setup HTTP and HTTPS versions
of your application by passing it to node’s http.createServer()
and https.createServer()
:
...
var app = express();
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
For convenience, and smaller applications the app.listen()
method takes the same arguments,
wrapping in an HTTP server. The following are equivalent:
var app = express();
app.listen(3000);
and
var app = express()
, http = require('http');
http.createServer(app).listen(3000);
This however means that methods that are on node’s http.Server.prototype
are no longer
present on app
, for example app.address()
must now be called on the server returned by app.listen()
or the one you have wrapped with http.createServer(app)
.
Socket.IO compatibility
Socket.IO’s .listen()
method takes an http.Server
instance as an argument. As of 3.x, the return value of express()
is not an http.Server
instance. (See the Application function section above.) To get Socket.IO working with Express 3.x, make sure you manually create and pass your http.Server
instance to Socket.IO’s .listen()
method.
var app = express()
, http = require('http')
, server = http.createServer(app)
, io = require('socket.io').listen(server);
server.listen(3000);
Template engine integration
Express 2x template engine compatibility required the following module export:
exports.compile = function(templateString, options) {
return a Function;
};
Express 3x template engines should export the following:
exports.__express = function(filename, options, callback) {
callback(err, string);
};
If a template engine does not expose this method, you’re not out of luck, the app.engine()
method allows you to map any function to an extension. Suppose you had a markdown library and wanted to render .md
files, but this library did not support Express, your app.engine()
call may look something like this:
var markdown = require('some-markdown-library');
app.engine(‘md’, function(path, options, fn){
fs.readFile(path, ‘utf8’, function(err, str){
if (err) return fn(err);
str = markdown.parse(str).toString();
fn(null, str);
});
});
View system changes
By removing the concept of a “layout” & partials in Express 3.x template engines will have greater control over file I/O. This means integration with template engines much easier, and greatly simplify the view system’s internals.
This also enables template engines to supply their own means of inheritance, for example later releases of Jade provide Django-inspired template inheritance, where the view being rendered specifies the layout it wants to extend. For an example of this using the Jade engine visit http://www.devthought.com/code/use-jade-blocks-not-layouts/
Post-release we may end up building an Express extension to support the old partial()
concept.
To get back layout functionality with EJS you can use express-partials or ejs-locals.
Error handling middleware
The app.error(callback)
method in 2.x was effectively the same as the following:
app.error = function(fn){
this.use(function(err, req, res, next){
fn.apply(this, arguments);
});
};
The reason for this is that Connect differentiates between “regular” middleware,
and “error-handling” middleware via the fn.length
. A regular middleware has a fn.length
of <= 3
, aka (req, res, next)
, whereas error-handling middleware must have exactly 4
(err, req, res, next)
. So the reason 2.x wrapped this functionality was to simply provide a bit of sugar on-top of this
API making the parameters optional.
In short all you need to do to “catch” these errors that are passed along is to define another middleware, but with 4
arguments. Note that this middleware should be defined below all the others, so that they may invoke next(err)
in order to pass an error to it like so:
app.use(express.bodyParser())
app.use(express.cookieParser())
app.use(express.session())
app.use(app.router) // the router itself (app.get(), app.put() etc)
app.use(function(err, req, res, next){
// if an error occurs Connect will pass it down
// through these "error-handling" middleware
// allowing you to respond however you like
res.send(500, { error: 'Sorry something bad happened!' });
})
App- & Request-level local variables
Do not use name
as a key in app.locals or res.locals because those objects are Function object instances. Any attempt to set them will be silently ignored. Other unstable or unusable top level keys are listed here: Function Instance Properties
关于Express的视图助手和路由分配,你可以使用Express的内置中间件和一些扩展库来实现这些功能。以下是一些示例代码和说明:
视图助手
视图助手(View Helpers)可以用来在视图中添加一些通用的功能,比如日期格式化、字符串处理等。Express本身没有内置的视图助手,但你可以通过中间件或者自定义函数来实现。
示例代码
const express = require('express');
const app = express();
// 定义一个简单的视图助手
app.locals.dateFormat = function(date) {
return date.toLocaleDateString();
};
app.set('views', './views'); // 设置视图目录
app.set('view engine', 'ejs'); // 设置模板引擎
app.get('/', (req, res) => {
const today = new Date();
res.render('index', { today });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在这个例子中,我们在app.locals
上添加了一个dateFormat
函数,这样你可以在任何视图中直接调用它。
路由分配
路由分配是指将不同的请求路径映射到不同的处理函数。Express提供了非常强大的路由机制来实现这一点。
示例代码
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Home Page');
});
app.get('/about', (req, res) => {
res.send('About Page');
});
app.get('/contact', (req, res) => {
res.send('Contact Page');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在这个例子中,我们定义了三个路由 /
, /about
, 和 /contact
,分别处理不同的HTTP GET请求。
MongoDB 连接
关于连接MongoDB,你可以使用Mongoose库来简化操作。首先确保你安装了Mongoose:
npm install mongoose
示例代码
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/mydatabase', {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => {
console.log('Connected to MongoDB');
}).catch((error) => {
console.error('Failed to connect to MongoDB:', error);
});
以上就是关于Express视图助手和路由分配的基本介绍和示例代码。希望对你有所帮助!