@@ -66,29 +66,6 @@ var TodoList = Backbone.Collection.extend({
6666 }
6767} ) ;
6868
69- // Create our global collection of **Todos**.
70- var Todos = new TodoList ( ) ;
71-
72- var TodoFilter ;
73-
74- var Workspace = Backbone . Router . extend ( {
75- routes :{
76- '*filter' : 'setFilter'
77- } ,
78-
79- setFilter : function ( param ) {
80- // Set the current filter to be used
81- TodoFilter = param . trim ( ) || '' ;
82-
83- // Trigger a collection filter event, causing hiding/unhiding
84- // of Todo view items
85- Todos . trigger ( 'filter' ) ;
86- }
87- } ) ;
88-
89- var TodoRouter = new Workspace ( ) ;
90- Backbone . history . start ( ) ;
91-
9269var Utils = {
9370 // https://gist.github.com/1308368
9471 uuid : function ( a , b ) { for ( b = a = '' ; a ++ < 36 ; b += a * 51 & 52 ?( a ^ 15 ?8 ^ Math . random ( ) * ( a ^ 20 ?16 :4 ) :4 ) . toString ( 16 ) :'-' ) ; return b } ,
@@ -111,7 +88,7 @@ var ENTER_KEY = 13;
11188
11289var TodoItem = React . createClass ( {
11390 getInitialState : function ( ) {
114- return { editValue : this . props . todo . title } ;
91+ return { editValue : this . props . todo . get ( ' title' ) } ;
11592 } ,
11693 onKeyUp : React . autoBind ( function ( event ) {
11794 this . setState ( { editValue : event . target . value } ) ;
@@ -127,16 +104,16 @@ var TodoItem = React.createClass({
127104 } ) ,
128105 render : function ( ) {
129106 return (
130- < li class = { cx ( { completed : this . props . todo . completed , editing : this . props . editing } ) } >
107+ < li class = { cx ( { completed : this . props . todo . get ( ' completed' ) , editing : this . props . editing } ) } >
131108 < div class = "view" >
132109 < input
133110 class = "toggle"
134111 type = "checkbox"
135- checked = { this . props . todo . completed ? 'checked' : null }
112+ checked = { this . props . todo . get ( ' completed' ) ? 'checked' : null }
136113 onChange = { this . props . onToggle }
137114 />
138- < label onDoubleClick = { this . onEdit } > { this . props . todo . title } </ label >
139- < button class = "destroy" onClick = { this . props . onDestroy } />
115+ < label onDoubleClick = { this . onEdit } > { this . props . todo . get ( ' title' ) } </ label >
116+ < button class = "destroy" onClick = { this . props . onDestroy } />
140117 </ div >
141118 < input ref = "editField" class = "edit" value = { this . state . editValue } onKeyUp = { this . onKeyUp } />
142119 </ li >
@@ -166,56 +143,64 @@ var TodoFooter = React.createClass({
166143
167144var TodoApp = React . createClass ( {
168145 getInitialState : function ( ) {
169- return { todos : Utils . store ( 'todos-react' ) , newTodoValue : '' , editing : { } } ;
146+ return { newTodoValue : '' , editing : { } } ;
147+ } ,
148+ // Here is "the backbone integration." Just tell React whenever there *might* be a change
149+ // and we'll reconcile.
150+ componentWillMount : function ( ) {
151+ this . props . todos . on ( 'add change remove' , this . forceUpdate , this ) ;
152+ } ,
153+ componentWillUnmount : function ( ) {
154+ this . props . todos . off ( null , null , this ) ;
170155 } ,
171156 handleKeyUp : React . autoBind ( function ( event ) {
172157 this . setState ( { newTodoValue : event . target . value } ) ;
173158 var val = event . target . value . trim ( ) ;
174159 if ( event . nativeEvent . keyCode !== ENTER_KEY || ! val ) {
175160 return ;
176161 }
177- var todos = this . state . todos ;
178- todos . push ( { id : Utils . uuid ( ) , title : val , completed : false } ) ;
179- this . setState ( { todos : todos , newTodoValue : '' } ) ;
162+ this . props . todos . add ( new Todo ( { id : Utils . uuid ( ) , title : val , completed : false } ) ) ;
163+ this . setState ( { newTodoValue : '' } ) ;
180164 } ) ,
181165 toggleAll : function ( event ) {
182166 var checked = event . nativeEvent . target . checked ;
183- this . state . todos . map ( function ( todo ) {
184- todo . completed = checked ;
167+ this . props . todos . map ( function ( todo ) {
168+ todo . set ( ' completed' , checked ) ;
185169 } ) ;
186- this . setState ( { todos : this . state . todos } ) ;
187170 } ,
188171 toggle : function ( todo ) {
189- todo . completed = ! todo . completed ;
190- this . setState ( { todos : this . state . todos } ) ;
172+ todo . set ( 'completed' , ! todo . get ( 'completed' ) ) ;
191173 } ,
192174 destroy : function ( todo ) {
193- this . setState ( { todos : this . state . todos . filter ( function ( candidate ) { return candidate . id !== todo . id ; } ) } ) ;
175+ this . props . todos . remove ( todo ) ;
194176 } ,
195177 edit : function ( todo ) {
196- this . state . todos . map ( function ( todo ) { this . state . editing [ todo . id ] = false ; } . bind ( this ) ) ;
197- this . state . editing [ todo . id ] = true ;
198- this . setState ( { editing : this . state . editing } ) ;
178+ var editing = { } ;
179+ editing [ todo . get ( 'id' ) ] = true ;
180+ this . setState ( { editing : editing } ) ;
199181 } ,
200182 save : function ( todo , text ) {
201- todo . title = text ;
202- this . state . editing [ todo . id ] = false ;
203- this . setState ( { todos : this . state . todos , editing : this . state . editing } ) ;
183+ todo . set ( 'title' , text ) ;
184+ this . setState ( { editing : { } } ) ;
204185 } ,
205186 clearCompleted : function ( ) {
206- this . setState ( { todos : this . state . todos . filter ( function ( todo ) { return ! todo . completed } ) } ) ;
187+ this . props . todos . filter ( function ( todo ) {
188+ return todo . get ( 'completed' ) ;
189+ } ) . map ( this . props . todos . remove . bind ( this . props . todos ) ) ;
190+ } ,
191+ componentDidUpdate : function ( ) {
192+ Utils . store ( 'todos-react' , this . props . todos ) ;
207193 } ,
208194 render : function ( ) {
209- Utils . store ( this . props . localStorageKey || 'todos-react' , this . state . todos ) ;
210195 var footer = null ;
211196 var main = null ;
212- var todoItems = this . state . todos . map ( function ( todo ) {
213- return < TodoItem todo = { todo } onToggle = { this . toggle . bind ( this , todo ) } onDestroy = { this . destroy . bind ( this , todo ) } onEdit = { this . edit . bind ( this , todo ) } editing = { this . state . editing [ todo . id ] } onSave = { this . save . bind ( this , todo ) } /> ;
197+ var todoItems = this . props . todos . map ( function ( todo ) {
198+ return < TodoItem todo = { todo } onToggle = { this . toggle . bind ( this , todo ) } onDestroy = { this . destroy . bind ( this , todo ) } onEdit = { this . edit . bind ( this , todo ) } editing = { this . state . editing [ todo . get ( 'id' ) ] } onSave = { this . save . bind ( this , todo ) } /> ;
214199 } . bind ( this ) ) ;
215200
216- var activeTodoCount = this . state . todos . filter ( function ( todo ) { return ! todo . completed } ) . length ;
201+ var activeTodoCount = this . props . todos . filter ( function ( todo ) { return ! todo . get ( ' completed' ) } ) . length ;
217202 var completedCount = todoItems . length - activeTodoCount ;
218- if ( activeTodoCount || completedCount ) {
203+ if ( activeTodoCount || completedCount ) {
219204 footer = < TodoFooter count = { activeTodoCount } completedCount = { completedCount } onClearCompleted = { this . clearCompleted . bind ( this ) } /> ;
220205 }
221206
@@ -250,5 +235,4 @@ var TodoApp = React.createClass({
250235 ) ;
251236 }
252237} ) ;
253-
254- React . renderComponent ( < TodoApp /> , document . getElementById ( 'todoapp' ) ) ;
238+ React . renderComponent ( < TodoApp todos = { new TodoList ( Utils . store ( 'todos-react' ) ) } /> , document . getElementById ( 'todoapp' ) ) ;
0 commit comments