9

我一直在玩 React/Flux,但在处理对权限敏感的操作时遇到了麻烦。

首要问题:当未登录的访问者尝试要求他/她登录的操作时,Flux 的方式是什么(a)检查用户是否已登录,(b)启动登录流程,(c ) 完成动作就成功了?

以论坛应用程序为例,该应用程序需要用户登录才能发帖:

我们有一个评论表单组件(主要取自 FB 的 React tut),如下所示:

var CommentForm = React.createClass({
  handleSubmit: function ( e ) {
    e.preventDefault();

    // get data
    commentData = {
      content: this.refs.content.getDOMNode().value.trim()
    };

    this.props.onCommentSubmit( commentData );
    this.resetForm();
  },

  resetForm: function () {
    this.refs.content.getDOMNode().value = '';
  },

  render: function () {
    return (
      <form className="comment-form" id="comment-form" onSubmit={ this.handleSubmit }>
        <textarea name="comment[content]" placeholder="What's on your mind?" ref="content"></textarea>
        <button className="post-comment button" type="submit">Post</button>  
      </form>
    )
  }
});

评论商店(缩写)

var CHANGE_EVENT = 'change';
var _comments = {};

function createComment ( data ) {
  // post to server
}

var CommentStore = React.addons.update(EventEmitter.prototype, {$merge: {

  // omitted methods

  dispatcherIndex: AppDispatcher.register(function(payload) {
    var action = payload.action;
    var text;

    switch(action.actionType) {
      case CommentConstants.ADD_COMMENT:
        AppDispatcher.waitFor([SessionStore.dispatchToken])
        createComment(action.data);
        break;
    }

    return true;
  })
}});

还有一个处理会话的商店(也缩写):

var CHANGE_EVENT = 'change';

function ensureCurrentUser () {
  if ( !SessionStore.currentUser() ) {
    app.router.navigate('/login');
  }
}

var SessionStore = React.addons.update(EventEmitter.prototype, {$merge: {

  // omitted code

  currentUser: function () {
    return app.context.current_user;
  },

  dispatchToken: AppDispatcher.register(function ( payload ) {
    var action = payload.action;

    switch(action.actionType) {
      case CommentConstants.ADD_COMMENT:
        ensureCurrentUser();
        break;
    }

    return true;
  })
}});

我最初的想法是,这是 FluxwaitFor()方法的一个案例。但是,上面的实现失败了,waitFor因为一旦设置就关闭依赖循环SessionStore.dispatchToken(一旦ensureCurrentUser返回)。

在这种情况下,负载应该被传递到ensureCurrentUser,然后再传递到路由处理程序中/login吗?处理这些类型的流的 Flux 方式是什么?

提前致谢 :)

4

3 回答 3

7

正如 FakeRainBrigand 在他的回答中所建议的那样,您只需通过首先从 SessionStore 检索该值来检查用户是否具有有效的会话,然后再创建评论:

case CommentConstants.ADD_COMMENT:
  if (SessionStore.getUser()) {
   createComment(action.data);
  }
  break;

但是为了保留评论以便在用户登录后创建它,我会在 CommentStore 中创建一个待处理评论的集合,然后,在登录验证和会话创建的回调中,调度一个新的操作来通知用户现在已经登录的 CommentStore。然后 CommentStore 可以通过从待处理的评论中创建真正的评论来响应它。

于 2014-10-12T20:42:57.837 回答
3

最简单的就是询问 SessionStore 是否有会话。

 case CommentConstants.ADD_COMMENT:
    if (SessionStore.getUser()) {
       createComment(action.data);
    }
    break;

当然,这只是为您节省了服务器请求。行为不应该与总是调用有任何不同createComment(action.data)

在这种情况下,负载应该传递到 ensureCurrentUser,然后传递到 /login 的路由处理程序吗?处理这些类型的流的 Flux 方式是什么?

为此,您可能希望有一个发出“登录”事件的事件发射器。

 case CommentConstants.ADD_COMMENT:
    if (SessionStore.getUser()) {
       createComment(action.data);
    }
    else {
       someEventEmitter.one('login', function(){
           createComment(action.data);
       });
       someEventEmitter.emit('loginRequired');
    }
    break;

当 loginRequired 发出时,如果没有用户登录,则会显示登录视图。

于 2014-10-12T19:55:49.807 回答
3

应该注意的是,react-router repo 中有一个名为auth-flow的示例,它阐明了如何做到这一点。虽然,我仍在努力使其对我有用,但在此处添加很有用。

于 2014-10-19T14:07:59.070 回答