Skip to content

Instantly share code, notes, and snippets.

@andrewfritz86
Created October 23, 2014 00:18
Show Gist options
  • Save andrewfritz86/8b69466f9a49758c8d4a to your computer and use it in GitHub Desktop.
Save andrewfritz86/8b69466f9a49758c8d4a to your computer and use it in GitHub Desktop.
Todo app taskview.js explanation

#task_view.js

function TaskView(model){
  console.log('view created with model:', model);
  this.$el   = $("<li>");
  this.model = model;
  }

This is our constructor function for TaskView objects. We can pass it a model as a parameter. The console will log the details of that model for us. Each TaskView object will have two attributes set automatically. The first is the element we will use to ultimately append it to the DOM. The model object we pass to the the constructor is also an attribute. This is just like our StudentView constructor that we used last week.

###prototype

We define some methods on our TaskView constructor that each TaskView object will be able to use.

  template: _.template($("#task-template").html()),

Here is our trusty mind-blowing template method. We use underscore to make a template from the task-template div in our html. This method will return a function expecting values for the keys in our erb, in this case 'completed' and 'description'.

  render: function() {
    console.log('  view:render', this);
    var temp = this.template({task: this.model});
    this.$el = $(temp); // reset el

    return this; // for chaining!
  },

First, we log the object being rendered to the console.

Next, we declare a variable temp and set it equal to the the templated version of our object's model attribute. We are passing the values for our template's keys ('completed' and 'description') to template, which in turn spits out a string of HTML with those keys inserted and ready to be rendered.

Lastly, we reset the object's $el attribute to no longer be an empty <li>, but rather an <li> with a full string of HTML that now includes our attributes as rendered by the template function. mindblown

  init: function() {
    console.log('  view:init', this);
    var view = this; // make it more semantic below...

    // build the element and then add to the DOM
    view.render();
    $("#tasks").append(view.$el);

    // attach event listeners, et al
    view.$el.on("click", "input",       view, view.toggleCompleted);
    view.$el.on("click", "span.remove", view, view.remove);

    return this; // for chaining!
  },    

First, we log the object.

Next, we set the variable view to the object, to make it more semantic.

Next, we call the render method on our object, which returns the object with it's $el attribute all templated and ready to go.

Next, we append the $el attribute to the DOM, which has an empty <ul> waiting for us.

Next, we attach two event listeners, listening for clicks on our new elements. We pass settings to each to make sure the events are filtered to the right places, as our listeners are actually being attached to the whole <li>, but we only want them fired at certain times. These listeners call two methods, which will be defined shortly.

Lastly, we make sure to return the object for chaining.

  toggleCompleted: function(event) {
    console.log('-> view:toggleCompleted', event.data);

    // this is the DOM node
    // event.data refers to the view instance (set in the handler above)
    event.data.$el.find("span.description").toggleClass('completed');

    // message the model
    event.data.model.toggleCompleted();
  },

This next part is tricky. We call data on the Event object, and in turn grab the $el which returns the whole <li>. We call the jQuery find method on that and grab the 'description' span, call the jQuery method toggleClass on the span, and set it to 'completed'. Jesus.

Lastly, we grab the model attribute from the view and call it's toggleCompleted method on it, so we can let the database know about the change, so it persists. The model has it's own toggleCompleted method, which I will (hopefully) get to.

  remove: function(event) {
    console.log('-> view:remove', event.data);

    // remove from the DOM
    event.data.$el.remove();

    // remove from global list!
    // http://stackoverflow.com/questions/208105/how-to-remove-a-property-from-a-javascript-object
    delete todoApp.taskViews[event.data.viewId];

    // message the model
    event.data.model.destroy();
  }

This method's purpose is to remove the event from the DOM, and from the database.

Here, we use the same method as above, going through the Event object to grab the whole <li>, (which is the $el attribute), and remove it from the DOM with jQuery's remove method.

Next, we delete the whole object from the global namespace.

Finally, we grab the model from the Event data, and call jQuery's destroy method on it, and poof, it is gone forever. RIP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment