Browse Source

Level 4: syncing model and view.

Frederic G. MARAND 6 years ago
parent
commit
4f605972d3
4 changed files with 55 additions and 12 deletions
  1. 4 0
      web/client/css/index.css
  2. 2 0
      web/client/index.html
  3. 49 7
      web/client/src/todos.js
  4. 0 5
      web/data/items.json

+ 4 - 0
web/client/css/index.css

@@ -0,0 +1,4 @@
+.complete {
+  color: #bbb;
+  text-decoration: line-through;
+}

+ 2 - 0
web/client/index.html

@@ -3,9 +3,11 @@
   <head>
     <meta charset="UTF-8">
     <title>Backbone</title>
+    <link rel="stylesheet" href="css/index.css" />
   </head>
   <body>
 
+    <h1>Todo list</h1>
     <div id="app"></div>
 
     <script src="./node_modules/jquery/dist/jquery.js"></script>

+ 49 - 7
web/client/src/todos.js

@@ -2,8 +2,8 @@
  * @see Model.url
  */
 $(function () {
-  const onChange = (...args) => {
-    console.log('On change', args, TodoItem);
+  const onChange = (change, x) => {
+    console.log('On change', change.changed);
   };
 
   // Create a model class.
@@ -14,10 +14,21 @@ $(function () {
     },
     // RESTful web service, RoR flavor.
     urlRoot: '/server/todos',
-  });
 
-  // Create a model instance to load it by ID.
-  const todoItem = new TodoItem({ id: 1 });
+    toggleStatus(view) {
+      if (this.get('status') === 'incomplete') {
+        this.set('status', 'complete');
+      }
+      else {
+        this.set('status', 'incomplete');
+      }
+      this.save();
+    }
+  }
+  );
+
+  // Create a model instance to load it by ID. Let it be global for console use.
+  todoItem = new TodoItem({ id: 1 });
 
   // Listeners
   todoItem.on('change', onChange);
@@ -58,15 +69,46 @@ $(function () {
     className: 'todo',
 
     // Underscore templating.
-    template: _.template('<h3><%= description %></h3>'),
+    //language=HTML
+    template: _.template(`
+<h3 class="<%= status %>">   
+  <input type="checkbox" 
+    <% if (status === "complete") print("checked") %> /> 
+  <%= description %>
+</h3>
+`),
+
 
     events: {
       // Generates this.$el.('h3", 'click', alertStatus).
       'click h3': 'alertStatus',
+
+      'change input': 'toggleStatus',
+    },
+
+    // Backbone.
+    initialize() {
+      // Backbone on() takes (event, callback, context)
+      this.model.on('change', this.render, this);
+      // Or without an explicit context, use a bound function.
+      // this.model.on('change', this.render.bind(this));
+      this.model.on('destroy', this.remove, this);
     },
 
+    // Handle on destroy.
+    remove() {
+      this.$el.remove();
+    },
+
+    // Handle "click h3"
     alertStatus() {
-      alert('Hey, you clicked the H3');
+      // Noisy.
+      // alert('Hey, you clicked the H3');
+    },
+
+    // Handle "change input".
+    toggleStatus() {
+      this.model.toggleStatus();
     },
 
     render: function () {

+ 0 - 5
web/data/items.json

@@ -1,9 +1,4 @@
 {
-    "1": {
-        "description": "Remember the milk",
-        "status": "complete",
-        "id": 1
-    },
     "2": {
         "status": "unfinished",
         "description": "second",