Nodejs OnceIO 的模块拦截与注入:模板文件路由重定向与 Model 数据改写
Nodejs OnceIO 的模块拦截与注入:模板文件路由重定向与 Model 数据改写
OnceAcademy
模块路由拦截与数据填充改写
OnceIO 的模块路由和模板注入机制是与其它 Web 框架最主要的区别之一。OnceIO 是 OnceDoc 的底层框架。 软件系统时常需要针对不同的客户定制不同的功能。 OnceIO 的模块路由可以通过一个扩展包,对系统原有模板(Template)和填充数据(Model)进行重定向或复写。可以在不更改系统源代码的情况下,以非侵入的方式对系统进行深度定制和扩展。
项目组织结构
还是以一个简单的用户登录项目为例。项目中会有一个实现用户登录模块 form 。还有一个功能复写模块 override 。
override 模块因仅用来复写 form ,因此没有专门的 web/css/js 文件夹。项目文件如图所示:
原有登录模块的实现
form 的登录页面模板为 form.html ,它又引用了页头(head.html)和页脚(foot.html)模板文件。其中还会显示填充 Model 的 title 属性。
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='/form/css/form.css'>
</head>
<body>
<!--#include="head.html"-->
<h1>Hello {{=it.title}}</h1>
<form action='/form/login' method='get'>
<p>Username: <input type='text' name='username' value='admin' /></p>
<p>Password: <input type='text' name='password' value='123456' /></p>
<input type='submit' value='Login' />
</form>
<!--#include="foot.html"-->
<script src="/form/js/form.js"></script>
</body>
</html>
后台文件 form/svr/form.js 。为了方便比较,这里注册了两个模块: form 和 form2 ,其中 override 模块会复写 form2 的 Template 模板和 Model 数据。这里还通过 app.model 为全局 Model 添加了 title 属性。
/*
regist form module
*/
app.mod('form', './form/web')
app.mod('form2', './form/web')
//preload *.html
app.pre(‘form’, ‘.html’)
app.model({ title: ‘Login form’ })
app.get([’/form’, ‘/form2’], function(req, res) {
res.render(‘form.html’)
})
app.get(’/form/login’, function(req, res) {
var loginUser = req.query
if (loginUser.password == ‘123456’) {
req.session.user = loginUser
res.send(‘login success’)
} else {
res.send(‘bad login’)
}
})
app.pre 等效于 app.preload 即告诉 onceio 预加载指定类型的模板文件。 运行后访问 localhost:8054/form 的界面是这样的:
模块文件的路由重定向与复写
模块路由拦截改写是通过一个 middleware 中间件实现的, override 中声明的中间件会在 form2 的路由之前将所用到的 Template 模板文件进行重定向或者复写,并修改将向模板中填充的 Model 数据, form 和 form2 的路由过程如下图所示:
这里使用 res.model 来复写全局 model 的属性,并使用 res.template 来对模板文件进行重定向或修改, override/main.js 代码如下所示:
app.mod('override', './override')
app.pre('override', '.html')
app.use(’/form2’, function(req, res) {
res.model({
title : ‘Title override’
})
res.template({
‘head.html’: ‘override/head.html’
, ‘foot.html’: ‘’
})
req.filter.next()
})
上段代码将 header.html 模板文件重定向到了 override/head.html 。并删除了 foot.html 模板的内容(空字符串),即新的 /form2 将不会再显示页脚,最终效果如图所示:
模块的这种路由重写机制可以让我们以最小代价对现有系统进行深度定制,同时确保了在满足不同客户的定制要求时,系统核心代码的一致性。
附:
- 原文地址 OnceDoc Helper
- 示例源码 Github
在Node.js中,OnceIO模块可以用于实现中间件的拦截与注入,这在需要对模板文件路由进行重定向或改写Model数据时非常有用。下面是一个简要的示例,展示如何通过OnceIO模块实现这些功能。
首先,确保你已经安装了OnceIO模块:
npm install onceio
接下来,你可以编写一个中间件来拦截和注入逻辑。例如,拦截请求并重定向到另一个路由,或者修改Model的数据。
const onceIO = require('onceio');
const express = require('express');
const app = express();
// 示例Model
class MyModel {
constructor(data) {
this.data = data;
}
getData() {
return this.data;
}
}
// 中间件拦截与注入
app.use(onceIO((req, res, next) => {
if (req.path === '/old-route') {
// 重定向到/new-route
res.redirect('/new-route');
} else if (req.path === '/new-route') {
// 改写Model数据
req.model = new MyModel({ modified: true });
}
next();
}));
app.get('/new-route', (req, res) => {
res.send(`Model data: ${JSON.stringify(req.model.getData())}`);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在这个示例中,我们创建了一个OnceIO中间件,用于检查请求路径,并在必要时进行重定向或修改Model数据。当访问/old-route
时,请求会被重定向到/new-route
,而在/new-route
上,Model数据会被修改并返回。