我有一个带有多个复选框的模态。就像模式滤波器...
因此,如果我选中了复选框,请关闭模态并再次打开它,必须单击选中的复选框。 (在这里,我真的不知道该怎么做:/)
如果我选中了该复选框并单击“清洁过滤器” button
,则所有checbkoxes必须未选中。 (在这里,我有一个方法可以做到,但不起作用:/)
有人可以帮助我吗?我该怎么办?
我在codeandbox上上传了代码,以查看其工作方式:CodeSandbox here
我的结构:
<button onClick={this.toggleDrawer(true)}>OPEN MENU</button>
<SwipeableDrawer
anchor="top"
open={this.state.top}
onClose={this.toggleDrawer(false)}
onOpen={this.toggleDrawer(true)}
>
<div style={{ padding: "15px" }}>
{data.map(element => {
return (
<div key={element.Name}>
<p>{element.Name}</p>
{element.Cont.map(item => {
return (
<FormControlLabel
key={item.id}
control={
<Checkbox
onChange={e => this.onChangeBox(e, item.id)}
checked={this.state.checkboxArray[item.id]}
iditem={item.id}
/>
}
label={item.contName}
/>
);
})}
</div>
);
})}
</div>
<div style={{ display: "flex", padding: "15px" }}>
<div onClick={this.toggleDrawer(false)}>
<button
style={{
background: "red",
color: "white",
padding: "9px"
}}
>
CLOSE
</button>
</div>
<div onClick={this.unChecked}>
<button
style={{
background: "blue",
color: "white",
padding: "9px"
}}
>
CLEAN ITENS
</button>
</div>
</div>
</SwipeableDrawer>
这是我打开/关闭模式的方法,选中复选框,然后取消选中它们:
toggleDrawer = open => event => {
console.log("clicou");
if (
event &&
event.type === "keydown" &&
(event.key === "Tab" || event.key === "Shift")
) {
return;
}
this.setState({ top: open });
};
onChangeBox = (event, iditem) => {
this.handleCheckbox(event.target.checked, iditem);
let checkBoxCurrentState = this.state.checkboxArray;
checkBoxCurrentState[iditem] = !checkBoxCurrentState[iditem];
this.setState({
checkboxArray: checkBoxCurrentState
});
};
unChecked = () => {
let resetArray = new Array(data.length).fill(false);
this.setState({
checkboxArray: resetArray
});
};
答案 0 :(得分:0)
如果您想直接跳转到解决方案,请参阅工作沙箱:https://codesandbox.io/s/material-demo-rcs5p
下面,我将解释我所做的所有更新。
让我们尝试集中一些代码。除了直接映射位于沙箱顶部的data
数组外,我们还可以将该数组存储在您的状态中。
class MenuCheckbox extends React.Component {
state = {
drawerOpen: false,
data: data
};
....
然后,我们将迭代状态数组以在您的抽屉中呈现复选框。这样做的原因是我们每次进行更改时都具有更新的本地参考数据:
render() {
return (
<div>
<button onClick={this.toggleDrawer(true)}>OPEN MENU</button>
<SwipeableDrawer
anchor="top"
open={this.state.drawerOpen}
onClose={this.toggleDrawer(false)}
>
太好了,现在让我们看一下数据数组。为了使事情变得容易,我们应该为每个项目赋予checked
属性。这将有助于跟踪切换模态时应检查/不检查的项目。这样更干净,更明确。
对数据数组中的所有项目重复的示例:
{
Name: "Item 1",
Cont: [
{
id: 1,
contName: "Name 1",
checked: false
},
{
id: 2,
contName: "Name 2",
checked: false
},
{
id: 3,
contName: "Name 3",
checked: false
}
]
}
现在很酷,我们的数据结构已经很好地设置了。我们可以编写一些简洁的逻辑来更新复选框。查看数组,我们有一组项目{}
(级别1),其中每个项目都有自己的内部数组[]
(称为Cont
(级别2),该数组存储我们的复选框状态
因此,自然地,要创建一个可以针对右侧复选框的函数,我们至少需要2个参数,即一组外部项目的索引和内部Cont
项目的索引。点击复选框后,我们将触发此操作:
onChangeBox = (dataIndex, contIndex) => {
//turns our array into a string, then parses it back to an array. This is the best way to do a deep clone
const data = JSON.parse(JSON.stringify(this.state.data));
data[dataIndex].Cont[contIndex].checked = !data[dataIndex].Cont[contIndex]
.checked;
this.setState({
data: data
});
};
在函数中,首先我们克隆数组以避免任何间接的状态突变。然后使用该新数组,找到选中的复选框,并简单地将checked
属性设置为与当前属性相反的属性。最后,我们使用该新数据更新状态数组。
这将适用于检查和取消检查。
在这些复选框的呈现逻辑中,我们可以使用.map()
的第二个参数来传入相应项目的索引。我们可以通过每个续项的内部.map()
传递外部索引,而通过内部.map()
传递内部索引。
render() {
return (
<div>
<button onClick={this.toggleDrawer(true)}>OPEN MENU</button>
<SwipeableDrawer
anchor="top"
open={this.state.drawerOpen}
onClose={this.toggleDrawer(false)}
>
<div style={{ padding: "15px" }}>
{this.state.data.map((item, elementIndex) => {
return (
<div key={item.Name}>
<p>{item.Name}</p>
{item.Cont.map((contItem, contIndex) => {
return (
<FormControlLabel
key={contItem.id}
control={
<Checkbox
onChange={() =>
this.onChangeBox(elementIndex, contIndex)
}
checked={contItem.checked}
iditem={contItem.id}
/>
}
label={contItem.contName}
/>
);
})}
</div>
);
})}
</div>
最后要清除复选框,我们只需要一个函数即可创建全新的项目/复选框数组,其中所有contItem
的检查值都设置为false。因此,我们将使用.map()
和嵌套的.map()
。
unChecked = () => {
const { data } = this.state;
const updatedData = data.map(item => {
return {
...item,
Cont: item.Cont.map(contItem => {
return {
...contItem,
checked: false
};
})
};
});
this.setState({ data: updatedData });
};
几乎全部。希望这对您有所帮助!
答案 1 :(得分:0)