我在尝试创建一个使用React选择和取消选择其他单个复选框(全选/全选)的复选框时遇到了一个小问题。我已阅读http://facebook.github.io/react/docs/forms.html,发现 受控 和 非受控 <input> s 之间存在差异。我的测试代码如下:
<input>
var Test = React.createClass({ getInitialState: function() { return { data: [ { id: 1, selected: false }, { id: 2, selected: false }, { id: 3, selected: false }, { id: 4, selected: false } ] }; }, render: function() { var checks = this.state.data.map(function(d) { return ( <div> <input type="checkbox" data-id={d.id} checked={d.selected} onChange={this.__changeSelection} /> {d.id} <br /> </div> ); }); return ( <form> <input type="checkbox" ref="globalSelector" onChange={this.__changeAllChecks} />Global selector <br /> {checks} </form> ); }, __changeSelection: function(e) { var id = e.target.getAttribute('data-id'); var state = this.state.data.map(function(d) { return { id: d.id, selected: (d.id === id ? !d.selected : d.selected) }; }); this.setState({ data: state }); }, __changeAllChecks: function(e) { var value = this.refs.globalSelector.getDOMNode().checked; var state = this.state.data.map(function(d) { return { id: d.id, selected: value }; }); this.setState({ data: state }); } }); React.renderComponent(<Test />, document.getElementById('content'));
“全局选择器”按预期方式工作:选中后,将选中所有其他检查。问题在于,__changeSelection()当单击其他复选框之一时,不会触发处理程序。
__changeSelection()
我不知道进行这项工作的正确方法是什么。也许React模型不是模拟这种交互的最佳模型吗?我能做什么?
提前致谢
在你的render功能,范围this为checks映射功能是不同的render,这是你需要的范围__changeSelection,所以this.__changeSelection不会找到一个__changeSelection属性。如果.bind(this)在该映射函数的末尾添加a ,则可以将其作用域绑定this为render:
render
this
checks
__changeSelection
this.__changeSelection
.bind(this)
var checks = this.state.data.map(function(d) { return ( <div> <input type="checkbox" data-id={d.id} checked={d.selected} onChange={this.__changeSelection} /> {d.id} <br /> </div> ); }.bind(this));
附带说明一下,我只是将传递id给处理函数,而不是分配数据属性。这将消除在处理程序中定位该元素的需要:
id
var checks = this.state.data.map(function(d) { return ( <div> <input type="checkbox" checked={d.selected} onChange={this.__changeSelection.bind(this, d.id)} /> {d.id} <br /> </div> ); }.bind(this));
然后更新您的__changeSelection函数以id第一个arg形式传入,并删除属性查找行:
__changeSelection: function(id) { var state = this.state.data.map(function(d) { return { id: d.id, selected: (d.id === id ? !d.selected : d.selected) }; }); this.setState({ data: state }); }
这是所有示例放在一起的示例,以及一个jsfiddle可供您试用:
/** @jsx React.DOM */ var Test = React.createClass({ getInitialState: function() { return { data: [ { id: 1, selected: false }, { id: 2, selected: false }, { id: 3, selected: false }, { id: 4, selected: false } ] }; }, render: function() { var checks = this.state.data.map(function(d) { return ( <div> <input type="checkbox" checked={d.selected} onChange={this.__changeSelection.bind(this, d.id)} /> {d.id} <br /> </div> ); }.bind(this)); return ( <form> <input type="checkbox" ref="globalSelector" onChange={this.__changeAllChecks} />Global selector <br /> {checks} </form> ); }, __changeSelection: function(id) { var state = this.state.data.map(function(d) { return { id: d.id, selected: (d.id === id ? !d.selected : d.selected) }; }); this.setState({ data: state }); }, __changeAllChecks: function() { var value = this.refs.globalSelector.getDOMNode().checked; var state = this.state.data.map(function(d) { return { id: d.id, selected: value }; }); this.setState({ data: state }); } }); React.renderComponent(<Test />, document.getElementById('content'));