@samitouri / QOS-React-2 / commits / 56dbec46db
Fork 0

The library for web and native user interfaces.

Fix backbone todomvc example

petehunt committed May 30, 2013 at 03:35 UTC 56dbec46db99d5ba764714a585fe9ce17ec8dcd8
1 file changed +36 -52
examples/todomvc-backbone/js/app.js
+36 -52
@@ -66,29 +66,6 @@ var TodoList = Backbone.Collection.extend({
66 }
67 });
68
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 -
69 var Utils = {
70 // https://gist.github.com/1308368
71 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;
88
89 var TodoItem = React.createClass({
90 getInitialState: function() {
114 - return {editValue: this.props.todo.title};
91 + return {editValue: this.props.todo.get('title')};
92 },
93 onKeyUp: React.autoBind(function(event) {
94 this.setState({editValue: event.target.value});
@@ -127,16 +104,16 @@ var TodoItem = React.createClass({
104 }),
105 render: function() {
106 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})}>
108 <div class="view">
109 <input
110 class="toggle"
111 type="checkbox"
135 - checked={this.props.todo.completed ? 'checked' : null}
112 + checked={this.props.todo.get('completed') ? 'checked' : null}
113 onChange={this.props.onToggle}
114 />
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} />
117 </div>
118 <input ref="editField" class="edit" value={this.state.editValue} onKeyUp={this.onKeyUp} />
119 </li>
@@ -166,7 +143,15 @@ var TodoFooter = React.createClass({
143
144 var TodoApp = React.createClass({
145 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);
155 },
156 handleKeyUp: React.autoBind(function(event) {
157 this.setState({newTodoValue: event.target.value});
@@ -174,48 +159,48 @@ var TodoApp = React.createClass({
159 if (event.nativeEvent.keyCode !== ENTER_KEY || !val) {
160 return;
161 }
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: ''});
164 }),
165 toggleAll: function(event) {
166 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);
169 });
186 - this.setState({todos: this.state.todos});
170 },
171 toggle: function(todo) {
189 - todo.completed = !todo.completed;
190 - this.setState({todos: this.state.todos});
172 + todo.set('completed', !todo.get('completed'));
173 },
174 destroy: function(todo) {
193 - this.setState({todos: this.state.todos.filter(function(candidate) { return candidate.id !== todo.id; })});
175 + this.props.todos.remove(todo);
176 },
177 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});
181 },
182 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: {}});
185 },
186 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);
193 },
194 render: function() {
209 - Utils.store(this.props.localStorageKey || 'todos-react', this.state.todos);
195 var footer = null;
196 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)} />;
199 }.bind(this));
200
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;
202 var completedCount = todoItems.length - activeTodoCount;
218 - if (activeTodoCount || completedCount) {
203 + if (activeTodoCount || completedCount) {
204 footer = <TodoFooter count={activeTodoCount} completedCount={completedCount} onClearCompleted={this.clearCompleted.bind(this)} />;
205 }
206
@@ -250,5 +235,4 @@ var TodoApp = React.createClass({
235 );
236 }
237 });
253 -
254 -React.renderComponent(<TodoApp />, document.getElementById('todoapp'));
238 +React.renderComponent(<TodoApp todos={new TodoList(Utils.store('todos-react'))} />, document.getElementById('todoapp'));