Sails.js 用于用户注册的 flash 消息

Posted

技术标签:

【中文标题】Sails.js 用于用户注册的 flash 消息【英文标题】:Sails.js flash message for user registration 【发布时间】:2014-08-17 15:48:07 【问题描述】:

我正在关注 http://irlnathan.github.io/sailscasts/blog/2013/08/27/building-a-sails-application-ep4-handling-validation-errors-with-a-flash-message/ 的 Sail.js 教程

但是我遇到了一个小问题。在本教程中,作者使用他的用户文件夹中的注册文件并在用户控制器中分配路由。然后,他使用flash 将验证错误发送给用户。

但是在我的项目中,注册文件位于根文件夹中,我像这样从 routes.js 文件中分配路由

module.exports.routes = 

  '/': 
    view: 'index'
  ,

  '/register': 
    view: 'register'
  

;

现在的问题是在注册时使用 Flash 向用户显示验证错误。我在用户控制器(创建)中使用了以下内容,但它似乎不起作用

if (err)
    err.success = 0;
    console.log(err);
    req.session.flash = 
        err: err   
    
    req.flash('error', req.session.flash);
    return res.redirect('/register');

有什么建议吗?

Sails.js 版本here

【问题讨论】:

请在此处说明您的问题的完整解决方案。我添加了此处使用的最有可能的sails.js 版本,以使您的案例可重现。看来您的情况是由此处观察到的特定版本特征引起的***.com/q/25356827/54964 【参考方案1】:

编辑:有关更多信息,请参阅 Sails 文档here - 基本上,由于您使用的是静态路由,因此在呈现视图之前未应用任何策略,因此闪存策略不起作用。我建议在您的UserController 中添加一个register 操作,然后从那里调用res.view()。如果您想了解更多信息,还有一个 *** post 讨论了这个问题。

我确实为我自己的项目开发了一个替代方案,您可以尝试一下(也需要非静态路由)。

在您的api/policies 文件夹中,创建一个策略flash.js

// flash.js policy
module.exports = function(req, res, next) 
  res.locals.messages =  success: [], error: [], warning: [] ;

  if(!req.session.messages) 
    req.session.messages =  success: [], error: [], warning: [] ;
    return next();
  
  res.locals.messages = _.clone(req.session.messages);

  // Clear flash
  req.session.messages =  success: [], error: [], warning: [] ;
  return next();
;

此政策允许三种不同的闪存类型:成功、警告和错误。它将为每个会话创建一个空字典并在页面加载时将其清除。

我在api/services 中创建了一个服务FlashService.js 以更轻松地闪现消息:

// FlashService.js
module.exports = 
  success: function(req, message) 
    req.session.messages['success'].push(message);
  ,
  warning: function(req, message)  
    req.session.messages['warning'].push(message);
  ,   
  error: function(req, message) 
    req.session.messages['error'].push(message);
  

然后,在您的 config/policies.js 配置文件中,确保将 flash 策略分配给您要使用 flash 的控制器操作:

// config/policies.js
module.exports.policies = 
  '*': [true, 'flash'],
  'UserController': 
    'register': ['flash'],
    // any future actions that want flash
  ,
  'AnotherController': 
    'someAction': ['flash', 'somePolicy'],
  

要在您的 register 操作中闪现消息,只需使用 FlashService.success(req, message)。或者,您可以使用 FlashService.errorFlashService.warning,具体取决于您的 UI 样式的工作方式以及您希望在多大程度上区分 Flash 消息。

在你看来,你可以这样写:

<% if (messages && messages['error'].length > 0)  %>
  <div class="alert alert-danger">
  <% messages['error'].forEach(function(message)  %>
    <%= message %>
    <br>
  <% ); %>
  </div>
  <br>
<%  %>
<% if (messages && messages['warning'].length > 0)  %>
  <div class="alert alert-warning">
  <% messages['warning'].forEach(function(message)  %>
    <%= message %>
    <br>
  <% ); %>
  </div>
  <br>
<%  %>
<% if (messages && messages['success'].length > 0)  %>
  <div class="alert alert-success">
  <% messages['success'].forEach(function(message)  %>
    <%= message %>
    <br>
  <% ); %>
  </div>
  <br>
<%  %> 

当然,您必须将 div 类更改为与您的 UI 相关的任何类。

【讨论】:

您的解决方案看起来不错而且很有条理。我按照你的建议做了,但是在视图中我没有收到 messages 的任何值。 messages 始终未定义:/ 啊,由于静态路由,策略不适用。我要做的只是将您的register 视图映射到UserController 的操作。这也可能是 Flash 策略在您所遵循的教程中不起作用的原因。有关详细信息,请参阅 Sails 文档here。编辑了我上面的回复! 感谢您的解释! :) 如果您可以看一下,我添加了另一个与此相关的问题。谢谢你。 ***.com/questions/25356827/… 我完全不明白你为什么要使用_.clone()。有什么建议吗? 见this explanation on the difference between _.clone() and '='。本质上,您希望创建消息的副本,以便您可以清除它们以供用户下一步操作。这些 Flash 消息并不意味着在每次页面加载时都保持不变。【参考方案2】:

在像 rails 或 cakephp 这样的普通 mvc 中处理 flash 是这样的: $this->Flash->error('An Error Occurred Message');然后将其显示在一个元素中。

在sails中应该就这么简单。

在控制器中:req.flash('error', 'An Error Occurred Message');

在部分视图中:flash.ejs

<% if (req.session.flash)  %>

    <% if (req.session.flash.success)  %>
    <div data-alert class="alert-box success radius">
        <%= req.flash('success') %>
        <a href="#" class="close">&times;</a>
    </div>
    <%  %>

    <% if (req.session.flash.warning)  %>
    <div data-alert class="alert-box warning radius">
        <%= req.flash('warning') %>
        <a href="#" class="close">&times;</a>
    </div>
    <%  %>

    <% if (req.session.flash.error)  %>
    <div data-alert class="alert-box alert round">
        <%= req.flash('error') %>
        <a href="#" class="close">&times;</a>
    </div>
    <%  %>

<%  %>

关于布局:

<%- partial('partials/flash') %>

处理每个字段的错误消息应该是验证和 html 帮助程序的一部分。 (例如:https://gist.github.com/mikermcneil/8366092)

【讨论】:

【参考方案3】:

您可以添加此导出:

module.exports = function flash(req, res, next) 
  if (!req.session.flash) 
    req.session.flash = ;
    req.session.flash['success'] = [];
    req.session.flash['warning'] = [];
  
  next();
;

然后在视图中:

<% if (req.session.flash['success'].length > 0)  %>
<div class="alert alert-success">
  <%= req.session.flash['success'].pop() %>
</div>
<%  %>
<% if (req.session.flash['warning'].length > 0)  %>
<div class="alert alert-warning">
  <%= req.session.flash['warning'].pop() %>
</div>
<%  %>

您可以像这样在控制器中创建消息:

req.session.flash['success'].push('Updated successfully');

【讨论】:

以上是关于Sails.js 用于用户注册的 flash 消息的主要内容,如果未能解决你的问题,请参考以下文章

Sails.js 对套接字请求的授权

使用 Passport.js 和 Sails.js 注册后如何重定向到特定位置?

从 Sails.js 中的关联模型访问模型的属性

Sails.js 政策不适用于单个控制器

Sails.js:用户注册后如何使用sails-generate-auth返回访问令牌?

AngularJS +sails.js