React TODOList实例

var React = require("react");
var ReactDOM = require("react-dom");
var Header = require("./page/Header.jsx");
var Footer = require("./page/Footer.jsx");
var Timer = require("./component/Timer.jsx");

var Todolist = require("./component/TodoList.jsx")

class Main extends React.Component{
	constructor(){
		super();
		this.state = {
			todolist:"",
		}
	}
	handlerOnChange(event){
		this.setState({
			todolist:event.target.value
		})
	}
	handKeydown(event){
		/*如果键盘码等于13,说明是回车键*/
		if (event.keyCode!=13) {
			return;
		};
		var val = this.state.todolist.trim();
		if (val) {
			/*调用子组件的方法并传值*/
			this.refs.aa.onAdd(val);
		}

		
	}
    render(){
    	let self = this;
        return(
        	<div>
        		<h1>任务列表</h1>
        		
            	<input type="text" onChange={this.handlerOnChange.bind(this)}
            	onKeyDown={this.handKeydown.bind(this)}
            	/>
        		<Todolist ref="aa"/>
            </div>
            )
    }
}

ReactDOM.render(<Main/>,document.getElementById("uuu"));
var React = require("react");
var ReactDOM = require("react-dom");
/*这只是子组件*/
/*这个是设置的自动增长ID*/
var ids=0;
class todolist extends React.Component{
	constructor(){
		super();
		this.state={
			/*存储任务的数组*/
			arr:[],
			/*完成任务数的记录变量*/
			wancheng:0,
			/*未完成。。。*/
			weiwan:0,
			/*span样式名的记录变量*/
			className12:"todolist_li",
		}

	}
	/*增加任务的方法,有父组件index.jsx用refs调用传值val*/
	/*val是input任务输入框的value*/
	onAdd(val){
		this.state.arr.push({title:val,completed:false,id:ids++,bol:true})
		this.setState(this.state);
		this.state.zongshu=(this.state.arr).length;
		this.state.weiwan=this.state.zongshu-this.state.wancheng
	}
	/*checkbox的触发事件,该事件把标记完成是否的completed属性反转*/
	onCheck(event){
		/*首先获取CheckBox的value值也就是index数组下标*/
		let index = event.target.value;
		/*把标记取反,用来改变记录,等下用来标记span的样式*/
		this.state.arr[index].completed=!(this.state.arr[index].completed);
		// this.setState(this.state);
		// console.log(this.state.arr)
		/*记录未完成和完成的个数*/
		/*假如是完成了的*/
		if(this.state.arr[index].completed){
			/*那它的完成数就在基础上加一*/
			this.state.wancheng=this.state.wancheng+1;
			/*任务总数减完成数=未完成数*/
			this.state.weiwan=this.state.arr.length-this.state.wancheng
		}else{
			/*反之,假如已将被选为完成,那么就标记为未完成*/
			/*重新记录未完成个数*/
			this.state.wancheng=this.state.wancheng-1;
			this.state.weiwan=this.state.arr.length-this.state.wancheng
		}
		/*更新该数据,它会自动调用render方法重新把值渲染到视图*/
		this.setState(this.state)
	}
	/*删除任务方法*/
	deleteVal(){
		/*把原来的方法备份*/
		let arr = this.state.arr;
		/*从屁股删起删除*/
		for(let i=arr.length-1;i>=0;i--){
			/*假如标记为true,代表已完成,就干掉他*/
			if (arr[i].completed) {
				/*splice删除方法,第一个参数是从第几位开始删,删几条*/
				this.state.arr.splice(i,1);
			}
			/*把完成的任务数归零*/
			this.state.wancheng=0;
			/*重新计算未完成数*/
			this.state.weiwan=this.state.arr.length-this.state.wancheng
		}
		/*视图重新渲染*/
		this.setState(this.state)
	}

	/*转换显示span和输入input的方法*/
	onInput(event){
		/*触发该方法,可以通过以下的方法获取到DOM对象本体obj*/
		event = event ? event : window.event;
		var obj = event.srcElement ? event.srcElement : event.target;
		//这时obj就是触发事件的对象,可以使用它的各个属性
		//还可以将obj转换成jquery对象,方便选用其他元素
		/*这个obj就是触发方法的span或者input*/
		/*然后获取它的同级上一个元素,就是checkbox DOM节点,该节点记录了该list的index下标*/
		let index = obj.previousSibling.value
		/*获取该下表的bol标记,并取反*/
		let bol = !(this.state.arr[index].bol);
		/*重新设置该属性为原来的反值*/
		this.state.arr[index].bol=bol;
		/*重新渲染*/
		this.setState(this.state)
		// console.log(this.state.arr[index].bol);
	}
	/*这个方法是让改变后的input可以以改变item.title的值调用的是onChange方法*/
	onInputChange(event){
		/*同样跟上面一样,获取到该对象,然后获取上一个DOM,然后获取index*/
		event = event ? event : window.event;
		var obj = event.srcElement ? event.srcElement : event.target;
		let index = obj.previousSibling.value
		/*把当前的值赋给原来的title内容*/
		this.state.arr[index].title = event.target.value;
		/*重新渲染*/
		this.setState(this.state)
		// console.log(event.target.value)
	}

	/*渲染方法*/
	render(){
		/*存储数组用map循环遍历之后的值*/
		var todos = null;
		/*把arr遍历*/
		todos = this.state.arr.map(
			(item,index)=>{
				/*model是存储返回span和input的变量*/
				let model;
				/*如果他的值为true就返回span,否则返回input*/
				if(item.bol){
					/*这里span引用了三元表达式,根据completed属性来判断给文字加上什么样式*/
					model = <span onClick={this.onInput.bind(this)} className={(item.completed)?"change":"sapn1"}>{item.title}</span>
				}else{ 
					model = <input onBlur={this.onInput.bind(this)} onChange={this.onInputChange.bind(this)} type="text" value={item.title}/>
				}

				/*返回渲染后的样式加数据*/
				return <li key={item.id}>
				<input  type="checkbox" value={index} onChange={this.onCheck.bind(this)}/>
				{model}
				</li>
			}
		)
		/*这个才是渲染的方法*/
		return(
			<div>
			<ul id="ul1" className="todolist_li">
				{todos}
			</ul>
			<p>完成了{this.state.wancheng}个任务,还有{this.state.weiwan}个未完成<span onClick={this.deleteVal.bind(this)}>【完成】</span></p>
			</div>
			)
		todos="";
	}
}

module.exports = todolist;

猜你喜欢

转载自blog.csdn.net/jinqianwang/article/details/83119475