③ 为model订阅render方法,意思是每次model有变化都将重新渲染页面,这里的代码比较关键,按照代码所示,每次数据变化都应该执行render方法,如果list数量比较多的话,每次接重新渲染岂不是浪费性能,但真实使用过程中,可以看到React竟然是局部刷新的,他这个机制非常牛逼啊!
④ 最后执行了render方法,开始了TodoApp标签的渲染,我们这里再将TodoApp的渲染逻辑贴出来
1 render: function () { 2 var footer; 3 var main; 4 var todos = this.props.model.todos; shownTodos = todos.filter(function (todo) { 7 switch (this.state.nowShowing) { 8 case app.ACTIVE_TODOS: 9 return !todo.completed; 10 case app.COMPLETED_TODOS: 11 return todo.completed; 12 default: ; 14 } 15 }, this); todoItems = shownTodos.map(function (todo) { 18 return ( 19 <TodoItem 20 key={todo.id} 21 todo={todo} 22 onToggle={this.toggle.bind(this, todo)} 23 onDestroy={this.destroy.bind(this, todo)} 24 onEdit={this.edit.bind(this, todo)} 25 editing={this.state.editing === todo.id} 26 onSave={this.save.bind(this, todo)} 27 onCancel={this.cancel} 28 /> 29 ); 30 }, this); activeTodoCount = todos.reduce(function (accum, todo) { 33 return todo.completed ? accum : accum + 1; 34 }, 0); completedCount = todos.length - activeTodoCount; (activeTodoCount || completedCount) { 39 footer = 40 <TodoFooter 41 count={activeTodoCount} 42 completedCount={completedCount} 43 nowShowing={this.state.nowShowing} 44 onClearCompleted={this.clearCompleted} 45 />; 46 } (todos.length) { 49 main = ( 50 <section className="main"> 51 <input 52 className="toggle-all" 53 type="checkbox" 54 onChange={this.toggleAll} 55 checked={activeTodoCount === 0} 56 /> 57 <ul className="todo-list"> 58 {todoItems} 59 </ul> 60 </section> 61 ); 62 } ( 65 <div> 66 <header className="header"> 67 <h1>todos</h1> 68 <input 69 ref="newField" 70 className="new-todo" 71 placeholder="What needs to be done?" 72 onKeyDown={this.handleNewTodoKeyDown} 73 autoFocus={true} 74 /> 75 </header> 76 {main} 77 {footer} 78 </div> 79 ); 80 }
说句实话,这段代码不知为什么有一些令人感到难受......
① 他首先获取了注入的model实例,获取其所需的数据todos,注入点在:
② 然后他由自身状态机,获取真实要显示的项目,其实这里如果不考虑路由的变化,完全显示即可
1 getInitialState: function () { 2 return { 3 nowShowing: app.ALL_TODOS, 4 editing: null 5 }; 6 },
③ 数据获取成功后,便使用该数据组装为一个个独立的TodoItem标签:
1 var todoItems = shownTodos.map(function (todo) { 2 return ( 3 <TodoItem 4 key={todo.id} 5 todo={todo} 6 onToggle={this.toggle.bind(this, todo)} 7 onDestroy={this.destroy.bind(this, todo)} 8 onEdit={this.edit.bind(this, todo)} 9 editing={this.state.editing === todo.id} 10 onSave={this.save.bind(this, todo)} 11 onCancel={this.cancel} 12 /> 13 ); 14 }, this);
标签具有很多事件,这里要注意一下各个事件这里事件绑定与控制器上绑定有何不同
④ 然后其做了一些工作处理底部工具条或者头部全部选中的工作
⑤ 最后开始渲染整个标签: