简体   繁体   English

ReactJs中的可重用模式

[英]Reusable modal in ReactJs

I'm trying to create a service which will show a Confirm Dialog and catch user's action (Confirm/Cancel) and can be reusable in any Component with less attempt. 我正在尝试创建一个服务,该服务将显示“确认对话框”并捕获用户的操作(“确认” /“取消”),并且可以以更少的尝试在任何组件中重用。

What I tried so far (using React gateway to inject my Dialog) 到目前为止我尝试过的(使用React gateway注入我的对话框)

I create a service like: 我创建一个服务,如:

var createConfirm = function(options, onConfirm, onCancel) {
  options = options || {};
  var actions = [
    <FlatButton
      label="Cancel"
      primary={true}
      onClick={onCancel}
    />,
    <RaisedButton
      label="OK"
      primary={true}
      onClick={onConfirm}
    />,
  ];
  return (
    <Gateway into="confirm-modal">
      <Dialog
        title={options.title || 'Confirmation'}
        actions={actions}
        modal={true}
        open={true}
      >
        {options.content || 'Are you sure?'}
      </Dialog>
    </Gateway>
  )
}

export default createConfirm;

Then in my component, I inject this to render() function: 然后在我的组件中,将其注入render()函数:

...
{
   _this.state.isOpen && _this.confirmable
}

And whenever I need to show Confirm modal, I'll call 每当我需要显示确认模态时,我都会打电话给

this.confirmable = createConfirm({
  title: 'CONFIRM',
  content: 'Are you sure to do that'
}, function() {
  console.log('user confirm')
  _this.setState({
    isOpen: false
  });
}, function() {
  console.log('user cancel')
  _this.setState({
    isOpen: false
  })
});
this.setState({isOpen: true});

My problem 我的问题

What I do to close that Confirm dialog, as you can see, is set isOpen state to false so it won't be rendered. 如您所见,我关闭该确认对话框的操作将isOpen状态设置为false因此不会呈现它。 It's a little cheat and seems not a native way to close a Dialog (lose leaving animation, look weird ...). 这有点作弊,而且似乎不是关闭Dialog的本机方法(丢失动画,看起来很奇怪...)。

So how can I implement a service where I have full control to the Dialog? 那么如何在对对话框具有完全控制权的情况下实现服务?

Thank you! 谢谢!

 var Modal = React.createClass({ displayName: 'Modal', backdrop: function() { return <div className='modal-backdrop in' />; }, modal: function() { var style = {display: 'block'}; return ( <div className='modal in' tabIndex='-1' role='dialog' aria-hidden='false' ref='modal' style={style} > <div className='modal-dialog'> <div className='modal-content'> {this.props.children} </div> </div> </div> ); }, render: function() { return ( <div> {this.backdrop()} {this.modal()} </div> ); } }); var Confirm = React.createClass({ displayName: 'Confirm', getDefaultProps: function() { return { confirmLabel: 'OK', abortLabel: 'Cancel' }; }, abort: function() { return this.promise.reject(); }, confirm: function() { return this.promise.resolve(); }, componentDidMount: function() { this.promise = new $.Deferred(); return React.findDOMNode(this.refs.confirm).focus(); }, render: function() { var modalBody; if (this.props.description) { modalBody = ( <div className='modal-body'> {this.props.description} </div> ); } return ( <Modal> <div className='modal-header'> <h4 className='modal-title'> {this.props.message} </h4> </div> {modalBody} <div className='modal-footer'> <div className='text-right'> <button role='abort' type='button' className='btn btn-default' onClick={this.abort} > {this.props.abortLabel} </button> {' '} <button role='confirm' type='button' className='btn btn-primary' ref='confirm' onClick={this.confirm} > {this.props.confirmLabel} </button> </div> </div> </Modal> ); } }); var confirm = function(message, options) { var cleanup, component, props, wrapper; if (options == null) { options = {}; } props = $.extend({ message: message }, options); wrapper = document.body.appendChild(document.createElement('div')); component = React.render(<Confirm {...props}/>, wrapper); cleanup = function() { React.unmountComponentAtNode(wrapper); return setTimeout(function() { return wrapper.remove(); }); }; return component.promise.always(cleanup).promise(); }; $(function() { return $('.removable').click(function() { return confirm('Are you sure?', { description: 'Would you like to remove this item from the list?', confirmLabel: 'Yes', abortLabel: 'No' }).then((function(_this) { return function() { return $(_this).parent().remove(); }; })(this)); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/JSXTransformer.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> <div id="row"> <div class="well"> <ul> <li>Foo <a href="#" class="removable"><i class="glyphicon glyphicon-trash"></i></a></li> <li>Bar <a href="#" class="removable"><i class="glyphicon glyphicon-trash"></i></a></li> <li>Baz <a href="#" class="removable"><i class="glyphicon glyphicon-trash"></i></a></li> </ul> </div> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM