我是Meteor和React BootStrap的新手。我试图从React bootstrap模式向Meteor注册用户。我的用户注册代码工作得很好,但是一旦执行异步调用meteor Accounts.createUser,我的模态就会关闭。如果我删除对Accounts.createUser的调用,我的模态保持打开状态。
我希望模式保持打开状态,以防有任何错误,例如用户注册的电子邮件已经存在,我可以在模态字段本身旁边显示消息。如果异步调用完成后没有错误,我可以关闭模态。
任何帮助实现同样的帮助表示赞赏。请参阅下面我用来实现此目的的两个React组件。我使用登录控件作为单独的组件,以便我可以在登录屏幕不需要是模态的其他地方重用核心代码。 (我仍然处于测试模式,所以模态标签说Signin但我实际上是在创建一个创建用户。)
var Button = ReactBootstrap.Button;
var Modal = ReactBootstrap.Modal;
LoginModal = React.createClass({
getInitialState() {
return { show: false };
},
modalClosing(){
this.setState({ show: false });
},
render() {
let close = () => this.modalClosing();
let open = () => this.setState({ show: true});
return (
<div>
<Button bsStyle="primary"
bsSize="small"
onClick={open}>
Login
</Button>
<div className="modal-container">
<Modal show={this.state.show}
onHide={close}
container={this}
animation={true}
onRequestHide={close}
backdrop="static"
dialogClassName="custom-modal"
aria-labelledby="contained-modal-title">
<Modal.Header closeButton>
<Modal.Title className="h2" id="contained-modal-title">Sign in</Modal.Title>
</Modal.Header>
<Modal.Body>
<LoginControl showCloseButton="true" onCloseClick={close}/>
</Modal.Body>
</Modal>
</div>
</div>
);
}
});
var Button = ReactBootstrap.Button;
var ButtonInput = ReactBootstrap.ButtonInput;
var Input = ReactBootstrap.Input;
var Label = ReactBootstrap.Label;
LoginControl = React.createClass({
getInitialState() {
return {
disabled: true,
userStyle: null,
pwdStyle: null,
btnStyle: "primary"
};
},
resetValidation() {
this.setState({
disabled: true,
userStyle: null,
pwdStyle: null,
btnStyle: "primary"
});
},
validationState() {
let length = this.refs.input.getValue().length;
let btnStyle = 'danger';
if (length > 6) btnStyle = 'success';
else if (length > 4) btnStyle = 'warning';
let disabled = btnStyle !== 'success';
return { btnStyle, disabled };
},
showCloseButton(){
if (this.props.showCloseButton) {
return (<Button className="pull-right signin-modal-closebtn" bsSize="large" onClick={this.tryLogin}>Close</Button>);
}
return null;
},
handleChange(input, e) {
let validationState = this.validationState();
if (validationState != null) {
let value = e.target.value;
let btnStyle = validationState.btnStyle;
if (validationState.btnStyle === "success") {
btnStyle = null;
}
else {
if (input == "user") {
btnStyle = this.state.userStyle;
}
else if (input == "pwd") {
btnStyle = this.state.pwdStyle;
}
}
if (input === "user") {
this.setState({ user: value, userStyle: btnStyle });
}
else if (input === "pwd") {
this.setState({ pwd: value, pwdStyle: btnStyle });
}
}
this.setState(validationState);
},
login (){
Accounts.createUser({
email: this.state.user,
userName: this.state.user,
password: this.state.pwd,
profile: null
}, function (error) {
if (error) {
if (error.error === 403.1) {
this.setState({ user: this.state.user, userStyle: "error", pwdStyle: "error", validationMessage :error.message});
}
else if (error.error === 403.2) {
this.setState({ pwd: this.state.pwd, userStyle: "error", pwdStyle: null, validationMessage: error.message });
}
}
else {
this.props.onCloseClick();
//Router.go('/');
}
});
},
tryLogin(args) {
//args.preventDefault();
this.login(args);
},
render: function () {
return (
<div>
<Label class="sr-only">{this.state.validationMessage}</Label>
<Input type="email" id="inputEmail" placeholder="Email address" ref="input" bsSize="large" bsStyle={this.state.userStyle} required autofocus onChange={this.handleChange.bind(this,"user")}/>
<Input type="password" id="inputPassword" class="form-control" ref="input" bsSize="large" placeholder="Password" required onChange={this.handleChange.bind(this,"pwd")}/>
<div class="checkbox">
<Button bsStyle={this.state.btnStyle} className="pull-right" bsSize="large" disabled={this.state.disabled} onClick={this.tryLogin}>Sign in</Button>
{this.showCloseButton()}
<label>
<input type="checkbox" value="remember-me" /> Remember me
</label>
</div>
<br />
</div>
);
}
});