Backbone attempt #4080

I have neglected the blog for some time. I think it was due to the fact that I began working on a project in WordPress and it just wasn’t presenting me with the type of challenge that I want to focus on in this blog. Or maybe I just got lazy, one of the two.

I don’t mean to say WordPress isn’t challenging. I have worked with WP before but I’m far from an expert. I learned a lot about it and I learned as I built out the project – not always the best way to do things, but I think it came out pretty well. I created a (very simple) plugin, contributed to another, and built a child theme. I’m quite sure there are things I could have done better, but the site feels pretty solid and our client has a straightforward UI to work with to enter new content.

I’m now going to return to looking at backbone.js. It’s an MVC framework that I have looked at using previously, but I never got too far with it.

For one thing, is it just me or is the backbonejs.org home page daunting? The single-huge-scrolling-page thing is off-putting to me. I know the left hand navigation should alleviate my anxiety but it just doesn’t. I guess I’ll get used to it over time.

Fortunately I have a real-world project I get to dig into instead of needing to build something from scratch. The Fortified Studio Web site needs a small alteration, so I’m going to see what I can do about it.

Instead of listing all x Fortified projects, we want to list just y (where y = 5 for starters). I should be able to do this, right?

For starters, what is the present value of x? I have sadly never really used underscore.js, so I need to try it out. I see right away there is a method called size(). Let’s try it out.

Indeed it works like a charm. By running the following statement in the View’s render I find out Fortified is currently displaying 14 projects in its portfolio. Not too shabby.

console.log("# projects = " + _.size(this.collection.models));

Seems like it would be easy enough to limit the display to any number of projects. And providing a link to show the rest would also be easy to do (I think). But what about loading a specific number of additional projects? For example, what if we initially display five projects, then provide a load more button that will load up to five more and continue to display the load more button if more projects are available? We’d have to keep track of how many projects are currently displayed, but I can’t think of any other complications.

My View (“PortfolioView”) currently has a render method that triggers the rendering of all portfolio items, and a renderProject method that handles the rendering of each project. I’m going to add a renderProjectGroup method that will load, well, a group of projects. This will  replace render’s job of rendering all projects at once. Here’s the signature of the method I will create:

renderProjectGroup : function(start, begin) {}

My unfamiliarity with underscore.js flares up again. Is there a way to extract a subset from a collection like this – by providing a start and end index? None of the underscore methods are jumping out at me, so I’ll turn to Google.

< … googling but finding nothing … >

I thought for sure that would be a common issue. Stupid internet. I took a closer look at the underscore methods and I think I may have something.

The filter() method returns each element in a collection and returns a new collection comprised of the elements that pass a given test. The documentation doesn’t mention it, but if the second parameter passed to the filter is the index of the element being passed. We can then check for the value of the index in the filter, and cut the collection off after a given number. Like this:

var start = 0;
var end = 3;
var sublist = _.filter([1, 2, 3, 4, 5, 6], function(num, index){
     return (index >= start) && (index <= end);
});

The result is:

[1, 2, 3, 4]

Sweet. That seems to work. Here’s how it looks within the Fortified site:

renderProjectGroup : function(start, end) {
    var that = this;
    var subset = _.filter(this.collection.models, function(num, index){
        return (index >= start) && (index <= end);
    });

    _.each(subset, function (item) {
        that.renderProject(item);
    }, this); 
},

Still need to create a load more button that will call that renderProjectGroup. I’m not sure how to approach this in the best backbone way. Do I include the button in the HTML then add the functionality to a view or controller? Or do I use a view to generate the button then bind its events to a method in a view or controller? I’m going to stop here and continue tomorrow.

Leave a Reply