V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
newghost
V2EX  ›  Node.js

OnceIO 的模块拦截与注入:模板文件路由重定向与 Model 数据改写

  •  1
     
  •   newghost · 2017-01-03 09:30:21 +08:00 · 1797 次点击
    这是一个创建于 2881 天前的主题,其中的信息可能已经有所发展或是发生改变。

    OnceAcademy

    模块路由拦截与数据填充改写

    OnceIO 的模块路由和模板注入机制是与其它 Web 框架最主要的区别之一。OnceIO 是 OnceDoc 的底层框架。 软件系统时常需要针对不同的客户定制不同的功能。 OnceIO 的模块路由可以通过一个扩展包,对系统原有模板(Template)和填充数据(Model)进行重定向或复写。可以在不更改系统源代码的情况下,以非侵入的方式对系统进行深度定制和扩展。

    项目组织结构

    还是以一个简单的用户登录项目为例。项目中会有一个实现用户登录模块 form 。还有一个功能复写模块 override 。

    override 模块因仅用来复写 form ,因此没有专门的 web/css/js 文件夹。项目文件如图所示:

    module_override_folder

    原有登录模块的实现

    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 的界面是这样的:

    module_override_folder

    模块文件的路由重定向与复写

    模块路由拦截改写是通过一个 middleware 中间件实现的, override 中声明的中间件会在 form2 的路由之前将所用到的 Template 模板文件进行重定向或者复写,并修改将向模板中填充的 Model 数据, form 和 form2 的路由过程如下图所示:

    module_override

    这里使用 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 将不会再显示页脚,最终效果如图所示:

    module_override_folder

    模块的这种路由重写机制可以让我们以最小代价对现有系统进行深度定制,同时确保了在满足不同客户的定制要求时,系统核心代码的一致性。

    附:

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   965 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:06 · PVG 05:06 · LAX 13:06 · JFK 16:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.