如何在数组中推送复选框值?

时间:2019-04-13 10:36:45

标签: javascript reactjs

我正在用React构建一个 Treeview 应用程序,但有一些我没有解决的问题。

当我单击应用按钮时,我想将所有选择的值压入一个数组,但是当我单击取消按钮时,我要删除所有最后选择的值。< / p>

我的代码如下,请有人可以修改代码并为该解决方案提供帮助吗?

export default class TreeView extends Component {

constructor(props) {
    super(props);
    this.state = {
        checked: [],
        expanded: [],
        keyword:"",
        pushOn:[],
    };
}

onSearchInputChange = (event, data, searchedNodes) => {
    this.setState(prevState => {
        if (prevState.keyword.trim() && !data.value.trim()) {
            return {
                expanded: [],
                keyword: data.value
            };
        }
        return {
            expanded: this.getAllValuesFromNodes(searchedNodes, true),
            keyword: data.value
        };
    });
};

getHighlightText = (text, keyword) => {
    const startIndex = text.indexOf(keyword);
    return startIndex !== -1 ? (
      <span>
        {text.substring(0, startIndex)}
        <span style={{ color: "#2cb664" }}>
          {text.substring(startIndex, startIndex + keyword.length)}
        </span>
        {text.substring(startIndex + keyword.length)}
      </span>
    ) : (
        <span>{text}</span>
      );
  };

keywordFilter = (nodes, keyword) => {
    let newNodes = [];
    for (let n of nodes) {
        if(n.children) {
            const nextNodes = this.keywordFilter(n.children, keyword);
            if (nextNodes.length > 0) {
            n.children = nextNodes;
            } else if (n.label.toLowerCase().includes(keyword.toLowerCase())) {
            n.children = nextNodes.length > 0 ? nextNodes : [];
            }
            if (
            nextNodes.length > 0 ||
            n.label.toLowerCase().includes(keyword.toLowerCase())
            ) {
            n.label = this.getHighlightText(n.label, keyword);
            newNodes.push(n);
            }
        }else {
            if(n.label.toLowerCase().includes(keyword.toLowerCase())) {
                n.label = this.getHighlightText(n.label, keyword);
                newNodes.push(n);
            }
        }
    }
    return newNodes;
};

getAllValuesFromNodes = (nodes, firstLevel) => {
    if (firstLevel) {
        const values = [];
        for (let n of nodes) {
            values.push(n.value);
            if(n.children) {
                values.push(...this.getAllValuesFromNodes(n.children, false));
            }
        }
        return values;
    } else {
        const values = [];
        for (let n of nodes) {
            values.push(n.value);
            if(n.children) {
                values.push(...this.getAllValuesFromNodes(n.children, false));
            }
        }
        return values;
    }
};

shouldComponentUpdate(nextProps, nextState) {
    if(this.state.keyword !== nextState.keyword) {
        return true;
    }
    if ( !lodash.isEqual(this.state.checked, nextState.checked)) {
        return true;
    }
    if ( !lodash.isEqual(this.state.expanded, nextState.expanded)) {
        return true;
    }
    return true;
}

render () {
    let searchedNodes = this.state.keyword.trim()
  ? this.keywordFilter(lodash.cloneDeep(nodesData), this.state.keyword)
  : nodesData;
    return (
        <div style={{marginLeft:"30px", marginTop:"30px", width:"30%"}}>
            <div className="search">
                <Input style={{marginBottom:"10px", width:"100%"}}
                        icon="fas fa-search"
                        placeholder="Search Categories"
                        iconPosition="left"
                        onChange={(event, data) => {
                            this.onSearchInputChange(event, data, searchedNodes);
                        }}
                        className="Change"
                />
            </div>
            <hr></hr>                
            <div className="checkbox-tree">
                <CheckboxTree 
                        nodes={searchedNodes}
                        checked={this.state.checked}
                        expanded={this.state.expanded}
                        onCheck={checked => this.setState({ checked })}
                        onExpand={expanded => this.setState({ expanded })}
                        expandOnClick
                        onClick = { () => { console.log("clicked"); }}
                        showNodeIcon={false}
                        icons={{
                            expandClose: <i class="fas fa-chevron-right fa-xs"></i>,
                            expandOpen: <i class="fas fa-chevron-down fa-xs"></i>,
                        }}
                        nameAsArray={true}                            
                />
            </div>
            <div>
               <form class="butt">
                    <button type="button" onClick={this.cancel}>Cancel</button>
                    <button  onClick={this.pushOnArray}>Apply</button>
               </form>
            </div>
        </div>
    )
}

}

谢谢!

1 个答案:

答案 0 :(得分:0)

所以我不知道您的项目设置是什么,但是最简单的方法是:

export default class TreeViewParent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: [],
  };
  onSave = (newCheckedValues) => {
    this.setState({checked: newCheckedValues})
    // perform action based on selected values here
  }
  render() {
    return <TreeView checked={this.state.checked} save={this.onSave} />
  }
}

// I am omitting parts of this component that are not related to the problem
export default class TreeView extends Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: this.props.checked,
      expanded: [],
      keyword: "",
      pushOn:[],
    };
  }
  cancel = () => {
    this.props.save(this.props.checked)
    this.setState({checked: this.props.checked})
  }
  save = () => {this.props.save(this.state.checked)}
  render () {
    let searchedNodes = this.state.keyword.trim()
      ? this.keywordFilter(lodash.cloneDeep(nodesData), this.state.keyword)
      : nodesData;
    return (
      <div style={{marginLeft:"30px", marginTop:"30px", width:"30%"}}>
          <div className="search">
            <Input style={{marginBottom:"10px", width:"100%"}}
              icon="fas fa-search"
              placeholder="Search Categories"
              iconPosition="left"
              onChange={(event, data) => {
                this.onSearchInputChange(event, data, searchedNodes);
              }}
              className="Change"
            />
          </div>
          <hr></hr>                
          <div className="checkbox-tree">
            <CheckboxTree 
              nodes={searchedNodes}
              checked={this.state.checked}
              expanded={this.state.expanded}
              onCheck={checked => this.setState({ checked })}
              onExpand={expanded => this.setState({ expanded })}
              expandOnClick
              onClick = { () => { console.log("clicked"); }}
              showNodeIcon={false}
              icons={{
                expandClose: <i class="fas fa-chevron-right fa-xs"></i>,
                expandOpen: <i class="fas fa-chevron-down fa-xs"></i>,
              }}
              nameAsArray={true}                            
            />
          </div>
          <div>
            <form class="butt">
              <button type="button" onClick={this.cancel}>Cancel</button>
              <button  onClick={this.pushOnArray}>Apply</button>
           </form>
         </div>
       </div>
     )
}

另外,我看到您在不了解React基础知识的同时使用了诸如cloneDeep之类的“高级”东西。我建议您阅读react docs,因为我提供的答案是react的入门级概念。