我正在尝试创建一个服务,该服务将显示确认对话框并捕获用户的操作(确认/取消),并且可以在任何组件中重复使用,但尝试次数较少。
到目前为止我尝试了什么(使用React gateway
注入我的对话框)
我创建了一个服务:
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;
然后在我的组件中,我将其注入render()
函数:
...
{
_this.state.isOpen && _this.confirmable
}
每当我需要显示确认模式时,我都会打电话给
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});
我的问题
如您所见,关闭“确认”对话框的操作是将isOpen
状态设置为false
,因此不会进行渲染。它有点作弊,似乎不是关闭Dialog的本地方式(丢失动画,看起来很奇怪......)。
那么如何实现我对Dialog有完全控制权的服务呢?
谢谢!
答案 0 :(得分:3)
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));
});
});
&#13;
<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>
&#13;