【问题标题】:How do I repopulate form fields after validation errors with express-form?如何在使用 express-form 验证错误后重新填充表单字段?
【发布时间】:2012-05-22 16:58:59
【问题描述】:

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

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

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

那么你们如何重新填充以及您的应用程序流程是什么,您是 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
  }

});

【问题讨论】:

    标签: validation node.js express


    【解决方案1】:

    我正在使用 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;
    

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

    【讨论】:

      【解决方案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);
      

      【讨论】:

      • 好的,很酷。所以我的问题是我正在做重定向并且 res 被重置了。不过,我学到的是,在尝试重新填充具有“多级”名称/路径的字段时存在一个单独的问题,例如 project[title](使用猫鼬时通常是这种情况)。他们不会重新填充。将不得不深入研究 express-form ,看看它是否可以解决。
      【解决方案3】:

      我最近不得不处理类似的问题,并使用了两个节点模块:验证器和 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
      

      【讨论】:

        猜你喜欢
        • 2014-05-04
        • 1970-01-01
        • 1970-01-01
        • 2012-05-05
        • 1970-01-01
        • 1970-01-01
        • 2016-03-15
        • 2013-11-09
        • 1970-01-01
        相关资源
        最近更新 更多