#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.