6

使用 node.js 和 express (2.5.9) 和 express-form。

我应该如何使用提交的值重新填充表单字段?

我有get一条post路线。如果在发布表单时出现验证错误,我会将用户重定向回 get,问题是重新填充的本地变量没有显示(我确实有 autoLocals:true,所以我认为这是因为我正在重定向并且res是重启。)

那么你们如何重新填充以及您的应用程序流程是什么,res.send而不是res.redirect重新设置整个事情吗?这似乎是重复的。

这是我的发布路线的示例:

app.post(

  '/projects/:id'

  , form(field("title").required("title", "Title is required)
  , function (req, res){

  if (!req.form.isValid){
    res.redirect('/project/'+req.params.id+'/edit');
  }
  else{
    // save to db
  }

});
4

3 回答 3

7

我正在使用 expressjs4.0 在验证后重新填充表单字段:

router.route('/posts/new')
 .get(function(req, res) {
 res.render('posts/new', new Post({}));
});

下面 res.render 中的第二个参数将在视图中设置一些变量。

res.render('posts/new', new Post({}));

在我看来,我将表单字段设置如下:

...
<input type="text" name="title" value="<%- post.title %>">
<textarea name="article"><%- post.article %></textarea>
...

当您提交此表单时,它应该被您的路由器捕获,如下所示:

router.route('/posts')
  .post(function(req, res) {
    var post = new Post(req.body)
      post.save(function(err) {
       if (err) {
         res.locals.errors = err.errors;
         res.locals.post = post;
         return res.render('posts/new');
       }
      return res.redirect('/posts');
  });
  ...
})

这行代码重置了您视图中的表单域

res.locals.post = post;

我希望有人觉得这很有用;)

于 2015-01-16T16:35:45.100 回答
2

不确定这是否是最佳实践,但是当我验证失败时,我不会重定向我只是重新渲染视图(通常通过将控制权传递给“get”回调)。像这样的东西:

function loadProject(req,res, id){ /* fetch or create logic, storing as req.model or req.project */} 

function editProject(req,res){ /* render logic */ }

function saveProject(req,res){ 
    if(!req.form.isValid){ 
        editProject(req,res);
    }else{
        saveToDb(req.project);
        res.redirect('/project'+req.project.id+'/edit');
    }
}

app.param('id', loadProject);
app.get('/projects/:id/edit', editProject);
app.post('/projects/:id', saveProject);
于 2012-05-22T17:05:53.777 回答
1

我最近不得不处理类似的问题,并使用了两个节点模块:验证器和 flashify。

在表单视图中,我将表单字段配置如下:

div.control-group
        label.control-label Description
        div.controls
          textarea(name='eventForm[desc]', id='desc', rows='3').input-xxlarge= eventForm.desc

      div.control-group
        label.control-label Tag
        div.controls
          select(id='tag', name='eventForm[tag]')
            tags = ['Medjugorje', 'Kibeho', 'Lourdes', 'Fatima']
            for tag in tags
              option(selected=eventForm.tag == tag)= tag

注意表单域的命名约定。然后在我的配置文件中设置一个全局变量,它实际上只是表单首次加载时的占位符:

//locals
app.locals.eventForm = []; // placeholder for event form repopulation

验证逻辑在我的路由器文件中,如下所示:

 app.post('/posts', function(req, res){
    var formData = req.body.eventForm;
    var Post = models.events;
    var post = new Post();

    post.text          = formData.desc;
    post.tag           = formData.tag;

    // run validations before saving
    var v = new Validator();
    var isPostValid = true;

    // custom error catcher for validator, which uses flashify
    v.error = function(msg) {
     res.flash('error', msg);
     isPostValid = false;
    }

    v.check(post.text, "Description field cannot be empty").notEmpty();
    v.check(post.tag, "Tag field cannot be empty").notEmpty();

然后我检查是否有错误,如果有,将表单数据传回视图:

  // reject it
  res.render('Event.jade', {page: req.session.page, eventForm: formData});

请注意,此 evenForm 数据被传递回视图,该视图重新填充了默认值。

最后一步是在表单视图中包含 flashify 组件。

div(style='margin-top: 60px').container-fluid
      include flashify

flashify 视图的代码如下所示:

if (flash.error != undefined)
div.container
    div.alert.alert-error
        b Oops!
        button(type='button', data-dismiss='alert').close &times;
        ul
            each error in flash.error
                li= error
if (flash.success != undefined)
div.container
    div.alert.alert-success
        b Success!
        button(type='button', data-dismiss='alert').close &times;
        ul
            each success in flash.success
                li= success
于 2013-03-27T21:50:28.940 回答