如何使数组可编辑

时间:2018-10-09 15:44:02

标签: javascript reactjs

我想使ul中的列表可编辑。但是我不知道该怎么做。我有删除功能,但不能编辑。目前它是如此。我在输入中添加了一些内容,并将其添加到列表中,然后单击删除将其删除,但是我需要对其进行编辑。

这是我正在处理的一个简单的待办事项列表

**TodoItems.js**
import React, { Component } from 'react';

class TodoItems extends Component {
    constructor(props) {
        super(props);
        this.createTasks = this.createTasks.bind(this);
    }
    createTasks(item) {
        return (
          <div>
            <li
              onClick={() => this.delete(item.key)}
              key={item.key}
            >
              {item.text}
            </li><p onClick={() => this.edit(item.key)}>Edit</p>
          </div>
        )
    }

    delete(key) {
        console.log("Key is: " + key);
        this.props.delete(key);
    }

    edit(key) {
        this.props.edit(key);
    }

    render() {
        var todoEntries = this.props.entries;
        var listItems = todoEntries.map(this.createTasks)

        return (
            <ul className="theList">
                {listItems}
            </ul>
        )
    }
}

TodoList.js

export default TodoItems;

import React, {Component } from 'react';
import TodoItems from './TodoItems';

class TodoList extends Component {
    constructor(props) {
        super(props);

        this.state = {
            items: []
        };
        this.addItem = this.addItem.bind(this);
        this.deleteItem =  this.deleteItem.bind(this);
    }

    addItem(e) {
        if (this._inputElement.value !== "") {
            var newItem = {
                text: this._inputElement.value,
                key: Date.now()
            };

            this.setState((prevState) => {
                return {
                    items: prevState.items.concat(newItem)
                };
            });
        }

        this._inputElement.value = "";

        console.log(this.state.items);

        e.preventDefault();
    }

    deleteItem(key) {
        console.log("Key is deleteItem:" + key);
        console.log("Items at delete: " + this.state.items);
        var filteredItems = this.state.items.filter(function (item){
            return (item.key !== key)
        });

        this.setState({
            items: filteredItems
        });
    }

    editItem(key) {

    }

    render() {
        return (
            <div className="todoListMain" >
                <div className="header">
                    <form onSubmit={this.addItem}>
                        <input ref={(a) => this._inputElement = a}
                            placeholder="enter task">
                        </input>
                        <button type="submit">add</button>
                    </form>
                </div>
                <TodoItems entries={this.state.items}
                            delete={this.deleteItem}/>
            </div>
        )
    }
}

export default TodoList;

2 个答案:

答案 0 :(得分:0)

可以使用HTML元素的contentEditable属性解决该问题。 它还需要两个按钮“编辑/完成”和一个“删除”按钮。 选择“编辑”后,列表项变为可编辑状态,并且可以进行更改。单击完成后,更改将保存在状态项中。

class TodoItems extends Component {
constructor(props) {
super(props);
this.createTasks = this.createTasks.bind(this);
this.state = {showEditButton:true}
}
createTasks(item) {
   return 
   <div><li key={item.key}  contentEditable={item.editable}> {item.text} </li>
     <p onClick={() => this.delete(item.key)}>Delete</p>
      {this.state.showEditButton?<p onClick={() => this.edit(item.key)}>Edit</p>:<p onClick={() => this.done(item.key)}>Done</p>}
   </div>
   }

delete(key) {
console.log("Key is: " + key);
this.props.delete(key);
}

edit(key) {
this.props.edit(key);
this.setState({showEditButton:false})
}
done(key){
this.props.done(key);
this.setState({showEditButton:true})
}

render() {
var todoEntries = this.props.entries;
var listItems = todoEntries.map(this.createTasks)

return (
    <ul className="theList">
        {listItems}
    </ul>
 )
 }
}

TodoList组件的更改如下

class TodoList extends Component {
 constructor(props) {
 super(props);
 this.state = {
    items: []
  };
this.addItem = this.addItem.bind(this);
this.deleteItem =  this.deleteItem.bind(this);
this.editItem = this.editItem.bind(this);
this.doneItem = this.doneItem.bind(this);
}

addItem(e) {
  if (this._inputElement.value !== "") {
    var newItem = {
        text: this._inputElement.value,
        key: Date.now(),
        editable:false
    };

    this.setState((prevState) => {
        return {
            items: prevState.items.concat(newItem)
        };
    });
 }

this._inputElement.value = "";

console.log(this.state.items);

e.preventDefault();
}

deleteItem(key) {
var filteredItems = this.state.items.filter(function (item){
    return (item.key !== key)
});

 this.setState({
    items: filteredItems
});
}

editItem(key) {

 var itemsCopy = this.state.items;
 itemsCopy.map(h=>{if(h.key==key)h.editable=true})
 this.setState({items:itemsCopy})
}
doneItem(key){

var itemsCopy = this.state.items;
itemsCopy.map(h=>{if(h.key==key)h.editable=false})
this.setState({items:itemsCopy})
}

render() {
return (
    <div className="todoListMain" >
        <div className="header">
            <form onSubmit={this.addItem}>
                <input ref={(a) => this._inputElement = a}
                    placeholder="enter task">
                </input>
                <button type="submit">add</button>
            </form>
        </div>
        <TodoItems entries={this.state.items}
           delete={this.deleteItem} edit={this.editItem} done={this.doneItem}/>
    </div>
   )
 }
}

答案 1 :(得分:0)

您应该添加另一个组件,将其命名为TodoItem,以便可以分别管理每个项目中的状态。添加几个事件来处理编辑名称时的输入更改,仅此而已。

此外,不建议您将props中的一个称为key,因为React.js在内部使用它来检测集合中的某个元素是否被更改。

还不允许div元素作为ul的子元素,因此我建议您将ul替换为div

示例

let Component = React.Component;

// New component
class TodoItem extends Component {
  constructor(props) {
      super(props);
      this.state = {
        editMode: false
      }
  }
  
  onClickEdit = () => {
  	this.setState({
    	editMode: true
    })
  }
  
  
  onSubmit = (e) => {
  	e.preventDefault();
    let value = this.refs.input.value;
    this.props.edit(this.props.id, value);
    this.setState({editMode: false})
  }
  
  render(){
  	let props = this.props;
    return (
      <div>
        {!this.state.editMode && <span onClick={() => this.props.delete(props.id)}>{props.text}</span>}
        {this.state.editMode && <form onSubmit={this.onSubmit}>
          <input type='text' ref='input' defaultValue={props.text} />
          </form>}
        <p onClick={this.onClickEdit}>Edit</p>
        </div>
    )
  }

}

class TodoItems extends Component {
  constructor(props) {
      super(props);
      this.createTasks = this.createTasks.bind(this);
      this.state = {
        editMode: false
      }
  }
  createTasks(item) {
      return <TodoItem key={item.id} {...item} edit={this.edit} delete={this.delete}/>;
  }

  delete = (key) => {
      console.log("Key is: " + key);
      this.props.delete(key);
  }

  edit = (key, newValue) => {
    this.props.edit(key, newValue)
  }

  render() {
      var todoEntries = this.props.entries;
      var listItems = todoEntries.map(this.createTasks)

      return (
          <div className="theList">
              {listItems}
          </div>
      )
  }
}


class TodoList extends Component {
  constructor(props) {
      super(props);

      this.state = {
          items: []
      };
      this.addItem = this.addItem.bind(this);
      this.deleteItem =  this.deleteItem.bind(this);
  }

  addItem(e) {
      if (this._inputElement.value !== "") {
          var newItem = {
              text: this._inputElement.value,
              id: Date.now()
          };

          this.setState((prevState) => {
              return {
                  items: prevState.items.concat(newItem)
              };
          });
      }

      this._inputElement.value = "";

      console.log(this.state.items);

      e.preventDefault();
  }

  deleteItem(key) {
      console.log("Key is deleteItem:" + key);
      console.log("Items at delete: " + this.state.items);
      var filteredItems = this.state.items.filter(function (item){
          return (item.id !== key)
      });

      this.setState({
          items: filteredItems
      });
  }

  editItem = (id, newValue) => {
    let newItems = [].concat(this.state.items);
    let item = newItems.find(i=>i.id == id);
    item.text = newValue;
    this.setState({items: newItems});
  }

  render() {
      return (
          <div className="todoListMain" >
              <div className="header">
                  <form onSubmit={this.addItem}>
                      <input ref={(a) => this._inputElement = a}
                          placeholder="enter task">
                      </input>
                      <button type="submit">add</button>
                  </form>
              </div>
              <TodoItems entries={this.state.items}
              edit={this.editItem}
                          delete={this.deleteItem}/>
          </div>
      )
  }
}


ReactDOM.render(<TodoList />, document.querySelector('#app'))
<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>
<div id="app"></div>