node.js 的动态视图
发布于 11 年前 作者 ainepan 6258 次浏览 最后一次编辑是 8 年前

学习《Node.js开发指南》遇到一个问题:动态视图的实现问题 首先书中第五章sample中‘视图交互’一节: app.dynamicHelpers({ user:function(req,res){ return res.session.user; }, error:function(req,res){ var err = req.flash(‘error’); if(err.length) return err; else return null; }, success:function(req,res){ var succ = req.flash(‘success’); if(succ.length) return succ; else return null; } }); 此版本在Express 3.0之后就不支持了,网上介绍使用 res.locals代替: app.use(function(req,res,next){ var err = req.flash(‘error’); var success = req.flash(‘success’); res.locals.user = req.session ? req.session.user : null; res.locals.error = err.length ? err : null; res.locals.success = success.length ? success : null; next(); }); app.use(app.router); routes(app); 问题是我如此做一直没有效果,即视图的效果没有,我的请求不会调用这段逻辑,我在此方法里面断点debugger了,可是一直执行不到,直接导致res.locals.user,error,success的值一直都是undefinded。

我想请教大家,这个动态视图是如何实现的,我的问题出在哪里? var express = require(‘express’); var routes = require(’./routes’); var user = require(’./routes/user’); var http = require(‘http’); var path = require(‘path’); var util = require(‘util’); var flash = require(‘connect-flash’);

var app = express(); var engine = require(‘ejs-locals’); var MongoStore = require(‘connect-mongo’)(express); var settings = require(’./settings’); var sessionStore = new MongoStore({ db : settings.db }, function() { console.log(‘connect mongodb success…’); });

app.configure(function () { // all environments app.set(‘port’, process.env.PORT || 3000); //since express 3.0 use ejs-locals app.engine(‘ejs’, engine);

app.set(‘views’, __dirname + ‘/views’); app.set(‘view engine’, ‘ejs’); app.use(express.favicon()); app.use(express.logger(‘dev’)); app.use(express.bodyParser()); app.use(flash()); app.use(express.methodOverride());

app.use(express.cookieParser()); app.use(express.session({ secret:settings.cookieSecret, cookie : { maxAge : 60000 * 20 //20 minutes }, store:sessionStore }));

app.use(function(req,res,next){ var err = req.flash(‘error’); var success = req.flash(‘success’); res.locals.user = req.session ? req.session.user : null; res.locals.error = err.length ? err : null; res.locals.success = success.length ? success : null; next(); }); app.use(app.router); app.use(express.static(path.join(__dirname, ‘public’))); });

// development only if (‘development’ == app.get(‘env’)) { app.use(express.errorHandler()); } routes(app);

http.createServer(app).listen(app.get(‘port’), function(){ console.log('Express server listening on port ’ + app.get(‘port’)); }); 插件我也都装了: { “name”: “aine blog”, “version”: “0.0.1”, “private”: true, “scripts”: { “start”: “node app.js” }, “dependencies”: { “express”: “3.3.8”, “ejs”: “", “connect”: “1.8.5”, “connect-mongo”:">= 0.1.7", “mongodb”:">= 0.0.9", “connect-flash”:"” } } 是不是什么插件版本不兼容呢?请高手指教。。。。

2 回复

github 搜 cnode

它的配置文件拿下来

断点使用inspector

我自己debugger了过程,发现这段代码始终执行不到,准确的说是断点断不到(具体在什么时候执行无法考究): app.use(function(req,res,next){ var err = req.flash(‘error’); var success = req.flash(‘success’); res.locals.user = req.session ? req.session.user : null; res.locals.error = err.length ? err : null; res.locals.success = success.length ? success : null; next(); }); 我跟踪了传给engine的参数里是有flash()进去的值,原来是我的页面引用错了,我依然通过locals.user或者locals.error来引用了,其实不需要,直接使用error或者success即可取到相应的值。

思考:对于动态视图的实现逻辑: res.render = function(view, options, fn){ … options._locals = self.locals; … } 我猜想在我们flash的时候,就是把对应的值写到了self.locals容器里,然后在render方法中赋值给view的option,而在option中保存的格式已经和index定义的一样了,翻译成: [settings=[Object],user=undefined,error=[Array],success=null,title=“用户注册”, +1…] 这样就可以在页面上直接引用了! index中定义的是: app.get(’/reg’,function(req,res){ res.render(‘reg’,{ title: ‘用户注册’ }); }); 通过上面的代码,动态的加了user,error,success几个变量的定义。

综上是我的分析,终结此帖,谢谢大家!

回到顶部