Try Tuts+ Premium, Get Cash Back!
Diving into CanJS

Diving into CanJS

Tutorial Details
  • Language: JavaScript
  • Framework: CanJS

If you haven’t heard, there’s a new kid in town: CanJS. What better way to dive into what this new framework offers than to build a contacts manager application? When you’re done with this three-part series, you’ll have all the tools you need to build your own JavaScript applications!


Choosing the Right Tool

Building a JavaScript application without the right tools is difficult. While jQuery is great at what it does, a DOM manipulation library doesn’t provide any infrastructure for building applications. This is specifically why you need to use a library, like CanJS.

CanJS is a lightweight MVC library that gives you the tools you need to build JavaScript apps.

CanJS is a lightweight MVC library that gives you the tools you need to build JavaScript apps. It provides all the structure of the MVC (Model-View-Control) pattern, templates with live binding, routing support and is memory safe. It supports jQuery, Zepto, Mootools, YUI, Dojo and has a rich set of extensions and plugins.

In part one, you will:

  • Create a Control and View (client-side template) to display contacts
  • Represent data using Models
  • Simulate ajax responses using the fixtures plugin

Excited? You should be! Now let’s get coding.


Setting Up Your Folders And HTML

You’ll need to create a folder for your application. Inside this folder, you need four sub-folders: css, js, views and img. Your folder structure should look like this when you’re done:

  • contacts_manager
    • css
    • js
    • views
    • img

Save this as index.html:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>CanJS Contacts Manager</title>
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="css/contacts.css">
  </head>
  <body>
    <div class="container">
      <div class="row">
        <div class="span12">
          <h1>Contacts Manager</h1>
        </div>
      </div>
      <div class="row">
        <div class="span3">
          <div class="well">
            <nav id="filter"></nav>
          </div>
        </div>
        <div class="span9">
          <div id="create"></div>
          <div id="contacts"></div>
        </div>
      </div>
    </div>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
    <script src="js/can.jquery.min.js"></script>
    <script src="js/can.fixture.js"></script>
    <script src="js/contacts.js"></script>
  </body>
</html>

At the bottom of the page, we load jQuery, CanJS, the fixture plugin and your application code (contacts.js).

The CSS and images for this tutorial are in included in the source files, which can be downloaded above.

Building Your UI With Views

Views are client-side templates that are used to render parts of your app. CanJS supports multiple templating languages, but this tutorial will be using EJS (Embedded JavaScript), which is packaged with CanJS and supports live binding.

EJS templates look like HTML but with magic tags where you want dynamic behavior (using JavaScript). There are three types of magic tags in EJS:

  • <% CODE %> runs JavaScript code,
  • <%= CODE %> runs a JavaScript statement, and writes the escaped result into the resulting HTML,
  • <%== CODE %> runs a JavaScript statement and writes the unescaped result into the resulting HTML (used for sub-templates).

Templates can be loaded from a file or script tag. In this tutorial templates will be loaded from EJS files.


Displaying Contacts

To render contacts, you’ll need an EJS template. Save the following code as contactsList.ejs within your views folder:

<ul class="clearfix">
  <% list(contacts, function(contact){ %>
    <li class="contact span8" <%= (el)-> el.data('contact', contact) %>>
      <%== can.view.render('views/contactView.ejs', {
        contact: contact, categories: categories
      }) %>
    </li>
  <% }) %>
</ul>

contactLists.ejs will render a list of contacts. Let’s examine the template code here in more detail:

<% list(contacts, function(contact){ %>

The EJS list() helper invokes a callback function on each contact in the list. When used with an observable list, the list() helper will use live binding to re-run anytime the length of the list changes.

<li class="contact span8" <%= (el)-> el.data('contact', contact) %>>

The code above uses an element callback to add the contact instance to the data of the <li>. Everything after the arrow is wrapped in a function that will be executed with el set to the current element.

<%== can.view.render('views/contactView.ejs', {
  contact: contact, categories: categories
}) %>

This code renders the contactView.ejs sub-template for each contact. can.view.render() takes a template and data as its parameters and returns HTML.


Rendering A Single Contact

Sub-templates are an excellent way of organizing your views into manageable chunks. They also help simplify your templates and promote DRY (Don’t Repeat Yourself). Later in this tutorial, you’ll re-use this template to create contacts. Save this code as contactView.ejs in your views folder:

<a href="javascript://" class="remove"><i class="icon-remove"></i></a>
<form>
<div class="row">
  <div class="span2">
    <img src="img/contact.png" width="100" height="100">
  </div>
  <div class="span3">
    <input type="text" name="name" placeholder="Add Name" 
      <%= contact.attr('name') ? "value='" + contact.name + "'" : "class='empty'" %>>
    <select name="category">
      <% $.each(categories, function(i, category){ %>
        <option value="<%= category.data %>" <%= contact.category === category.data ? "selected" : "" %>>
          <%= category.name %>
        </option>
      <% }) %>
    </select>
  </div>
  <div class="span3">
    <label>Address</label>
    <input type="text" name="address" 
      <%= contact.attr('address') ? "value='" + contact.address + "'" : "class='empty'" %>>
    <label>Phone</label>
    <input type="text" name="phone" 
      <%= contact.attr('phone') ? "value='" + contact.phone + "'" : "class='empty'" %>>
    <label>Email</label>
    <input type="text" name="email" 
      <%= contact.attr('email') ? "value='" + contact.email + "'" : "class='empty'" %>>
  </div>
</div>
</form>

Each property of a contact is placed in an <input> tag. These will be used to add and update a contact’s information.


Making Your Views Live

Any time EJS encounters attr() while processing a template, it knows that the surrounding code should be turned into an event handler bound to that property’s changes. When the property is changed elsewhere in the app, the event handler is triggered and your UI will be updated. This is referred to as live binding. EJS Live binding is opt-in. It only turns on if you use attr() to access properties.

Let’s look at one of the <input> tags from the contactView.ejs to see how this works:

<input type="text" name="name" placeholder="Add Name" 
  <%= contact.attr('name') ? "value='" + contact.name + "'" : "class='empty'" %>>

The code in the magic tags will become an event handler bound to the contact’s name property. When we update the name property, the event handler is run and the HTML will be updated.


Organizing Application Logic Using can.Control

can.Control creates an organized, memory-leak free, stateful control that can be used to create widgets or organize application logic. You create an instance of a Control on a DOM element and pass it data your control will need. You can define any number of functions in your Control and bind to events.

When the element your Control is bound to is removed from the DOM, the Control destroys itself, cleaning up any bound event handlers.

To create a new Control, extend can.Control() by passing it an object containing functions you want to define. In part two, event handlers will be passed in as well.

There are a few important variables and functions present in every Control instance:

  • this – A reference to the Control instance
  • this.element – The DOM element that you created the instance on
  • this.options – An object containing any data passed to the instance when it was created
  • init() – Called when an instance is created

Managing Contacts

Add the following snippet to your contacts.js file to create the Control that will manage contacts:

Contacts = can.Control({
  init: function(){
    this.element.html(can.view('views/contactsList.ejs', {
      contacts: this.options.contacts,
      categories: this.options.categories
    }));
  }
})

When an instance of Contacts is created, init() will do two things:

  1. Uses can.view() to render contacts. can.view() accepts two parameters: the file or id of the script tag containing our template code and data. It returns the rendered result as a documentFragment (a lightweight container that can hold DOM elements).
  2. Inserts the documentFragment from can.view() into the Control’s element using jQuery’s .html().

Representing Data Using Models

A Model abstracts the data layer of an application. Two models are needed in this application: one for contacts and one for categories. Add this code to contacts.js:

Contact = can.Model({
  findAll: 'GET /contacts',
  create  : "POST /contacts",
  update  : "PUT /contacts/{id}",
  destroy : "DELETE /contacts/{id}"
},{});

Category = can.Model({
  findAll: 'GET /categories'
},{});

A model has five static methods that you can define to create, retrieve, update and delete data. They are findAll, findOne, create, update and destroy. You can overwrite these functions to work with any back-end, but the easiest way to define a Model is using REST service, as exemplified in the code above. You can safely omit any static methods that won’t be used in an application.

It’s important to point out here that the model instances in CanJS are actually what we call ‘observables’. can.Observe provides the observable pattern for objects and can.Observe.List provides the observable pattern for arrays. This means you can get and set properties using attr() and bind to changes in those properties.

The findAll() method returns a Model.list, which is a can.Observe.List that triggers events when an element is added or removed from the list.


Simulating a Rest Service Using Fixtures

Fixtures intercept AJAX requests and simulate their response with a file or function. This is fantastic for testing, prototyping or when a back-end isn’t ready yet. Fixtures are needed to simulate the REST service the models in this application are using.

But first, you’ll need some sample data for the fixtures to use. Add the following code to contacts.js:

var CONTACTS = [
  {
    id: 1,
    name: 'William',
    address: '1 CanJS Way',
    email: 'william@husker.com',
    phone: '0123456789',
    category: 'co-workers'
  },
  {
    id: 2,
    name: 'Laura',
    address: '1 CanJS Way',
    email: 'laura@starbuck.com',
    phone: '0123456789',
    category: 'friends'
  },
  {
    id: 3,
    name: 'Lee',
    address: '1 CanJS Way',
    email: 'lee@apollo.com',
    phone: '0123456789',
    category: 'family'
  }
];

var CATEGORIES = [
  {
    id: 1,
    name: 'Family',
    data: 'family'
  },
  {
    id: 2,
    name: 'Friends',
    data: 'friends'
  },
  {
    id: 3,
    name: 'Co-workers',
    data: 'co-workers'
  }
];

Now that you have some data, you need to wire it up to fixtures so you can simulate a REST service. can.fixture() takes two parameters. The first is the URL we want to intercept and the second is a file or function that is used to generate a response. Often URLs you want to intercept are dynamic and follow a pattern. In this case, you should use templated URLs. Simply add curly braces to the URL where you want to match wildcards.

Add the following to contacts.js:

can.fixture('GET /contacts', function(){
  return [CONTACTS];
});

var id= 4;
can.fixture("POST /contacts", function(){
  return {id: (id++)}
});

can.fixture("PUT /contacts/{id}", function(){
  return {};
});

can.fixture("DELETE /contacts/{id}", function(){
  return {};
});

can.fixture('GET /categories', function(){
  return [CATEGORIES];
});

The first four fixtures simulate the GET, POST, PUT and DELETE responses for the Contact model, and the fifth fixture simulates the GET response for the Category model.


Bootstrapping the Application

Your application has Models for your data, Views to render contacts, and a Control to hook everything up. Now you need to kickstart the application!

Add this to your contacts.js file:

$(document).ready(function(){
  $.when(Category.findAll(), Contact.findAll()).then(
    function(categoryResponse, contactResponse){
      var categories = categoryResponse[0], 
        contacts = contactResponse[0];

      new Contacts('#contacts', {
        contacts: contacts,
        categories: categories
      });
  });
});

Let’s take a closer look at what is happening in this code:

$(document).ready(function(){

Wait for the DOM to be ready using jQuery’s document ready function.

$.when(Category.findAll(), Contact.findAll()).then(
  function(categoryResponse, contactResponse){

Call findAll() on both models to retrieve all of the contacts and categories. Since findAll() returns a Deferred, $.when() is used to make both requests in parallel and execute a callback when they are finished.

var categories = categoryResponse[0], 
  contacts = contactResponse[0];

Get the list of model instances from the response of the two findAll() calls. The responses are arrays, with the first index being the list of model instances retrieved.

new Contacts('#contacts', {
  contacts: contacts,
  categories: categories
});

Create an instance of the Contact Control on the #contacts element. The list of contacts and categories are passed into the Control.

When you run your application in a browser, you should see a list of contacts:


Wrapping Up

That does it for part one of this series! You’ve been introduced to the core of CanJS:

  • Models abstract the data layer in your application
  • Views are templates that turn data into HTML
  • Controls wire everything up.

In the next lesson, you’ll create a Control and View to display categories and use routing to filter contacts. Hope to see you there!

Questions? Ask away below! Can’t wait to learn more? Part two of the series has been posted here!

Tags: canjs
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Steve

    Appears horribly messy. What happened to code separation???

  • http://jerfowler.com Jeremy Fowler

    Great, yet ANOTHER Javascript MVC framework. Because Backbone, Spine, Ember, Knockout, etc.. etc.. wasn’t good enough for some reason. I think that any new article discussing their brand new Javascript MVC library first needs to justify why it exists. What problem does it solve that the other ones completely ignore. What is it’s niche?

    • http://www.punchyourface.com Adam

      I agree.

    • Tony

      I was thinking the same thing!

    • http://bitovi.com Mihael Konjević

      It’s not really a new framework. It’s the MVC parts from http://javascriptmvc.com extracted under the different brand. So it actually predates all the frameworks you listed.

      • http://jerfowler.com Jeremy Fowler

        So… its not a NEW framework, Its a re-branded one… Great, that clears up everything except – why? Is it just J…MVC with better memory management? Why not just incorporate that into J…MVC? Why the separate websites? Is it just a marketing ploy? A way to make J…MVC more “hip” and “cool”? Why NOT start from scratch and clean up the syntax and make things more… clean. CanJS? nope…

      • http://montanaflynn.me/ Montana Flynn

        @Jeremy Fowler

        My question to you is why not? Someone created a set of tools for themselves and is offering them to you, for free. Maybe their is something you could learn this project wether it be cold, practices, or even a completely new workflow. Who cares if even a hundred js MVC libraries exist, that is good for everyone, competition is a great motivator and everyone can learn and progress our industry.

    • Nima

      I agree with Jeremy
      Why do we need a million javascript frameworks ?
      There are just so many options out there and each of them have their own syntax, etc.
      It is a waste of time to consider learning these until there is a really good reason to do so.

      • http://www.omnific.be/ Ben

        It’s a waste of time to complain about your options in life until someone forces you to use them.

    • Ivanhoe

      Had the same thought as soon as I read the title :)))

    • http://klep.co Marcio

      I agree with you , nice comment.

    • http://montanaflynn.me/ Montana Flynn

      Your missing the bigger picture here, the more choices people have the quicker they will adopt better coding practices. If I had only used Backbone I never would have found Knockout which fits my style much more. Who cares if even a hundred js MVC libraries exist, that is good for everyone, competition is a great motivator and everyone can learn and progress our industry.

      To everyone complaining about this tutorial or the CanJS project I have this to say to you: Someone created a set of tools for themselves and is offering them to you, for free. Maybe their is something you could learn this project wether it be cold, practices, or even a completely new workflow.

    • Ryan

      Because it’s lighter and faster than the other frameworks, it works with your favorite DOM library (jQuery, Zepto, Dojo, Mootools, YUI), and the full bundle (stealjs, documentjs, funcunit) allows for building massive applications which are linted, documented, tested, and minified in a way to satisfy Page Speed and Yslow as well as search engines (yes, your ajax app can be crawled if you use stealjs).

  • http://kriix.com Kristijan

    A thank you to the author for making this post, but still the library really seems messy, hard to learn and more complex then a standard jquery-object way of solving such things (and it will get even more complex once you add the code to filter the contacts or to remove them from the list)

    • http://bitovi.com Justin Meyer

      Kristijan,
      Removing items from the list is pretty easy because of the live-binding, you simply have to remove items from the observe-able list and the dom auto-updates.

      What specifically seems messy to you? Like most things, you have to learn it before it “seems” easy. If you think the standard jQuery object way is ideal, you might check out http://bitovi.com/blog/2010/10/writing-the-perfect-jquery-plugin.html which discusses a lot of the problems with this approach and the motivation for can.Control.

      Let me know what you find messy and maybe I can de-mystify it for you. I’m pretty sure I can show how CanJS can make many common patterns much more simple. We’re actually creating a CanJS Recipes site. I’ll even write you an example.

      Also, if you don’t write apps, and are typically just listening to a click here and a mouseenter there, CanJS, and most frameworks in general, will be overkill. These frameworks are for writing apps (I’d argue can.Control is awesome for widgets too), but not for “I need to add a tabs widget to my page”.

      Thanks!

  • http://bitovi.com Justin Meyer

    Jeremy,
    All your questions have a very good answer. So before everyone freaks out … let me answer them (I’ll respond to Ivanhoe as well).

    JavaScriptMVC was started over 4 years ago. It was originally MVC parts and something like RequireJS. But it has expanded far past a JavaScriptMVC library, including components for Testing, Documentation, Special jQuery events and even things like “crawl” which can make your website crawlable. The name JavaScriptMVC does not reflect what the library does anymore, it’s a bad name and will change.

    Furthermore, not everyone wanted all parts of JavaScriptMVC. The rise of Backbone, which was largely similar to the MVC parts of JavaScriptMVC (in API and size) clearly illustrated this.

    So lets tackle your questions:

    Is it just J…MVC with better memory management?

    It is the MVC parts of JMVC, with it’s API cleaned up, made to work from jQuery, YUI, Zepto, Dojo, and Mootools. We also added live-binding. JMVC has always had this memory management.

    Why not just incorporate that into J…MVC?

    Because people have long requested being able to use the MVC parts without the rest of the framework. And, the next version of JMVC will include CanJS.

    Why the separate websites?

    Because many developers find JMVC too intimidating and the learning curve too steep. We felt that an overview website of the MVC parts would help make our tools (which I believe are the best technology around) more approachable. You might notice that it’s documentation is on http://donejs.com. DoneJS is the next version of JMVC, so you can consider the http://canjs.us page a getting started guide.

    Is it just a marketing ploy?

    If think a marketing ploy is putting about 10 peoples effort for 4 months into improvements and making technology easier to use is a marketing ploy, then yes it’s a marketing ploy. JavaScriptMVC does not reflect what JavaScriptMVC is anymore. We wanted people to be able to use parts of it without other parts.

    Why NOT start from scratch and clean up the syntax and make things more… clean.

    We spend a ton of time making things more clean.

    Now the big question: WHY ANOTHER LIBRARY!!!!!

    You can find overviews of reasons here: http://bitovi.com/blog/2012/04/introducing-canjs.html and here: http://canjs.us/#why_canjs

    But for the lazy (like those who couldn’t find the Why CanJS link on http://canjs.us), I’ll give a short list:

    1. It’s memory safe
    2. It’s fast (it’s live-binding and control initialization are heavily optimized)
    3. It’s lightweight (smaller than Backbone and it’s underscore dependency) and includes live-binding
    4. It’s flexible, with deep integration with YUI, jQuery, Mootools, Zepto, Dojo
    5. It does things the “right way”. For example, model methods return deferreds, Observe handle’s nested properties, and once I finish my can.route article, you’ll see how awesome it can handle some really tricky routing behavior.
    6. It includes a bunch of supported 3rd party plugins.

    And again, it’s not another library, it’s just a massive clean up of part of existing libraries.

    But finally, being the main contributor of arguably the oldest currently maintained MVC library, I think it’s silly to complain about the expansion of JavaScript frameworks. It’s a great thing. Backbone and Knockout both influenced the development of CanJS. I’m betting that CanJS’s memory safety and use of deferreds influences Backbone.

    Competition is a good thing. It means that the web is still progressing. New ideas are still being developed and improvements made. Embrace change or you’ll be left behind.

    I believe CanJS is currently the best MVC library available in terms of features, size, and performance. Live binding within 8.5k! But I said currently. I look forward to strong competition.

    • http://jerfowler.com Jeremy Fowler

      OK, you cleared up a lot of my questions. Thank you. Now, I’m going to be a pain-in-the-a$$ and complain about your tutorial and your framework a bit more… bare with me….

      Lets start off with the file structure. Why aren’t you using separate dirs for models and controllers? Lumping everything into a single js dir will make things very unorganized. IMO

      Next is your index.html, I see your using twitter’s bootstrap. Many people are not fond of CSS frameworks in general. especially ones that aren’t semantic and require additional tags just for layout. In a tutorial, I would make the markup as light as possible.. Adding all the extra span12 span3 divs clutters things up and over complicates things.

      Ok, next is contactsList.ejs which is a BIG problem for me… That is SUPER complicated to look at. Plus, its supposed to be a view. Views are supposed to be logic-less; markup and variables – that’s it. You have functions, assignments, callbacks – all sorts of stuff going in a template that SHOULD NOT BE IN A TEMPLATE…. Templates are supposed to simple enough a designer could use… That is a whole ball of complex mess right there….

      Then there is contactView.ejs which isn’t as bad, but still… Your excessive use of ternary operators makes me sad…

      Finally, there is contacts.js which combines the model and controller code and initialization code into one file… Plus, its a global namespace polluter. tsk tsk… The fixtures idea seems like an inelegant way of doing things. A plugin system would be much better. I would also make use of local storage so your example actually worked… Where is the add and remove contact features? How do I save? Show me some dynamic updates! When I refresh the page, my changes should keep! Overall, the example is pretty weak for the amount of code that was written…

      I know you guys have put a lot of work into this, and I agree that competition is great. Where is it though? I still don’t see where this framework shines compared to the others. I want to be wow’d… Please wow me next time.

      Thanks for reading my opinion.

      • http://justin@bitovi.com Justin Meyer

        Thanks again for your thoughts. My response follows below:

        Lumping everything into a single JS dir will make things very unorganized.

        I couldn’t agree more. This is why we always split everything into it’s own files when we are using a dependency management tool like StealJS ore RequireJS. We didn’t want to create too many unnecessary steps. This tutorial isn’t on folder organization.

        I agree about the extra spans and CSS. But a lot of people like twitter’s bootstrap and I’m sure the author didn’t want to explain a bunch of CSS to get the app to look right.

        contactList.ejs is supposed to be a View …

        I think you might be confusing the responsibility of a view for that of a template. Due to the live-binding nature of EJS it’s more akin to a traditional MVC View then the dummy templates found in server side frameworks like ROR. Angular and Knockout’s templates are Views and can, for example, call on a click to code elsewhere. That being said these templates are not actually doing anything a “template-view” should not be doing. I’ll explain:

        The callback is simply an iterator, like jQuery’s $.each. It’s not a “async” callback. Just an easy way of looping.

        The assignment,

        (el)-> el.data(‘contact’, contact)

        is no more assignment then setting the className in any other template would be. It’s setting jQuery data so the model instance can be retrieved. Setting data in $.data so it can be retrieved later is an extremely common practice. W/o CanJS, you have iterate through your template and call $.data yourself. EJS allows you to this within the template. But if you look at an EJS template as producing DOM instead of a string, it’s not doing anything in the “the PHP is doing SQL” evil way.

        Templates are supposed to simple enough a designer could use

        It’s unlikely a designer would edit contactList.ejs. That’s not the design goal of EJS. Although, it’s based on ERB (rail’s template language), and I’m guessing that designers find that easy enough, that file does have a lot going on (in code to html ratio). But it’s only doing 3 things: looping through contacts, setting $.data, and calling a sub-template. It’s just that the only HTML is an “li” so it looks overly scary.

        Other templating languages have special syntaxes for looping and control. EJS uses simply JavaScript. We figured that having to learn a 3rd syntax is just as complex as having to learn JS’s control structures. I suppose we could have gone for-loop.

        We could have avoided calling a sub-template, likely making things more straightforward, but we wanted to show how that was done.

        In terms of contactView.ejs, I agree and suggested making a helper function that could be used like:

        To eliminate much of the perceived messiness. But, there’s no real avoiding an if/else of some sort. It has to be either in the template or in a helper method.

        Yes, combining things is bad and we don’t encourage it. It was simply to show how the parts worked, it isn’t a tutorial on folder/file organization. If you are looking for that, check out JavaScriptMVC which has a very strong one. We could wrap everything in a function to prevent global namespace pollution and add vars, but it’s a basic example. We can add that in future parts.

        What is inelegant about fixtures? This is a surprising critique because fixtures are pure awesome. We work on a ton of projects where the server-side is not done yet. Fixtures let us mock up our services and simply remove them (they are typically in their own file) when the service is working. We can also use them for testing. What do you mean by plugin system?

        I dislike all the localStorage examples because they don’t show how to deal with what most apps are doing -> making Ajax requests. Plus, fixtures are so handy that we wanted to highlight them.

        I think you’ll be impressed by how much is accomplished with few lines in the next segments. We had to do a lot of the grunt work in this section:

        Mock up the services
        Request data in parallel from those services and rendered it to the screen
        Setup a live-binding view, so now, all we have to do is change the data and the view auto-updates

        This is a tutorial and not intended to wow people. It’s meant to inform. I hope that the reasons I listed in my previous comment are at least sunshine to you.

        What would you like to see? What would wow you (in such a small, basic, example)?

        In terms of comparison against other frameworks, I’m wondering where they shine where this does not, in terms of the functionality displayed here.

        How do they hookup model instance data so it can be retrieved later?
        How do they parallel load data and get notified when both loads are complete if not supporting deferreds?
        How do they simulate ajax requests?

        I think that CanJS adds a few nice features here compared to Spine / Backbone / etc. Certainly nothing wow, but we haven’t gotten to CanJS’s good stuff (performance, memory safety, live-binding).

        If you want wow …

        First, backbonejs.org is down right now, but you can see the performance data here: http://jsperf.com/canjs-ejs-performance/5

        on the live-binding. Here’s a taste of the live-binding in action:

        http://jsfiddle.net/HcpFS/1/

        Notice how prettyDate just has to read an observe, dateObserve.attr(‘now’), and auto-magically becomes live. Imagine how hard it would be to write something similar efficiently (with only one timer that updates multiple items all at once for better UI responsiveness).

        Things get even trickier if the “due” property can change. Then you need prettyDate binding on that as well. EJS and Observe take care of this for you at blazing speed.

        I also made this special for you: http://jsfiddle.net/d3T9c/1/

        That shows how can.Control’s automatic memory cleanup works with templated event handlers. This might seem pretty basic, but in an MVC pattern, one is constantly binding on things outside whatever element you are on (like listening to changes in the model). Templated event handlers mean no memory leaks b/c you can’t forget to unbind. This should wow everyone who has enough experience with building JS apps to have seen how hard of a bug these issues are to find.

        Also, I’d check out our Todo MVC example and compare it to other frameworks.

        https://github.com/jupiterjs/cantodo/blob/master/jquery/todo.js

        It uses local storage, but there are parts of it that are essentially incredible. My favorite is:

        https://github.com/jupiterjs/cantodo/blob/master/jquery/todo.js#L77

        (the call to this.attr(‘length’) does not have to be there as of 1.0 production).

        This computes how many completed items there are in a todo list. This is used in the template here:

        https://github.com/jupiterjs/cantodo/blob/master/jquery/todo.ejs#L21

        But here’s what’s WOW Wooooow Wow wee WOW ….

        This is automatically live bound. If a todo changes from complete to incomplete, or a todo is added or removed, that part of the dom is automatically updated. You can implement the complete function how you would implement it without live-binding. EJS just figures this out and does the right thing super efficiently (if you, for example change multiple properties at once, it does not update the dom twice).

        You don’t have to write any code that listens to changes, you don’t have to write any code that goes and updates that part of the DOM, you simply write a completed function and EJS takes care of everything else.

        If that doesn’t blow your mind … nothing will. Thanks :-)

      • http://bitovi.com Justin Meyer

        My list helper got swallowed .. it was supposed to look like:

        inputFor(contact, “name”)

        inputFor would be implemented as function that could return the label and input element (and hide the ternary operator).

      • http://jerfowler.com Jeremy Fowler

        I debated whether or not to post yet AGAIN, but you DID ask me questions. So you brought this on yourself… However, I will try to keep this brief.

        IMO, views are supposed to be dumb. They display information about the model, that’s it. Controllers are supposed to handle events. I have a problem with your EJS views chocolate getting in your Controller’s peanut butter. per se. I am also not the only one who feels this way.

        http://www.artima.com/lejava/articles/stringtemplate.html

        As for fixtures and plugins, well… I’ll use Spine as an example. To add local storage support in Spine its as easy as this:

        var Contact = Spine.Model.sub();
        Contact.configure(“Contact”, “name”);
        Contact.extend(Spine.Model.Local);

        That’s it… To add ajax support to the model…

        var Contact = Spine.Model.sub();
        Contact.configure(“Contact”, “name”);
        Contact.extend(Spine.Model.Ajax);

        OMG! That’s is fraking easy! Now look at your todo example on github. You need 70 lines of code to add local storage to that model…

        You may brag about CanJS is small library, but if that small library comes at a cost me having to do extra typing – well no, thank you.

        Some examples of projects that wow me: Spinejs for one. Meteor also flat knocked me on my ass… Those types of projects that reduce the amount of code I have to personally write and are easy to read and understand just give me the warm and fuzzies..

        Here is a good read: http://destroytoday.com/blog/reasons-for-spinejs/

        I am in no way affiliated with any other the above projects… My opinions are my own…

        You should also get Addy to add you to his project: http://addyosmani.github.com/todomvc/

      • http://bitovi.com Justin Meyer

        Thanks again. No worries about the replies. Discussion is good.

        There’s no mixing of chocolate and peanut butter in this example nor any of our posted examples. You might be worried about the risk, but it’s an argument that moved from server-side templates to front-end templates but forgot about that clients need to always have their data prepped anyways. And dispute using EJS for 5 years, and writing hugely massive apps with big teams of varying skill sets, I’ve never once had a problem with EJS being used for evil …. except once, where someone put a tag in it, but that can’t be avoided by most template languages.

        On localStorage

        First, I’m pretty sure that’s a plugin. I can write a plugin for localStorage in about 2 seconds. JavaScriptMVC has one.

        Second,

        What you’ve written is not helpful for an app. Or at least the apps I’ve written. That might ONLY be useful for mobile. But when we use localStorage it’s used as:

        1. A place to store things that don’t need to be sent to the server (this is very limited and typically applies to some minimal state like, the user keeps this panel collapsed).
        2. An offline store or quick-response store

        For #1 you’d probably want to send this to the server anyway, but if you aren’t you certainly want cookies to back it up (unless you don’t care about IE, or the amount would increase http size too much).

        For #2 you wouldn’t have a separate model, you’d implement this “behind the scenes” in the model’s CRUD methods so no one even realizes its happening. I believe one of our guys is working on this right now. So, this type of “quick localStorage” model is not useful to most use cases we care about.

        On Ajax

        Is

        Contact = can.Model({
        findAll: ‘GET /contacts’,
        create : “POST /contacts”,
        update : “PUT /contacts/{id}”,
        destroy : “DELETE /contacts/{id}”
        },{});

        Category = can.Model({
        findAll: ‘GET /categories’
        },{});

        Really all that hard?

        If so, you do can.Model(“Task”), this does much the same thing, make requests to /tasks, /tasks/{id}. We don’t show this because most people don’t have the luxury of having perfectly matching service endpoints. Instead we show it’s next most common case:

        can.Model({findAll: “/tasks”});

        Which can further be changed to:

        can.Model({findAll: {url: “/tasks”, type: “json”})

        And further to

        can.Model({findAll: function(params){return $.get(‘/tasks’, params, ‘json’}})

        And so on with the needs of your app

        Which brings me to my bigger point …

        CanJS is really about scaling and flexibility. I promise that CanJS, in a big app, especially with live binding, it’s templated event handlers, etc would have you writing far less code than Spine. You’re going to want to add localStorage quick-hit caches and that sort of thing is easy to write.

        It seems a lot depends on what you are writing. If it’s a little demo todo app, yes having a localStorage plugin will help. But if you are writing a real app, it most likely wont. If you are writing a demo app that has perfect service endpoints for Spine, Spine will be nice to use to connect to it. If you are writing something with complex (and likely overlapping) endpoints, what do you do?

        Actually, event with a small app (and a localStorage plugin that I will write probably tonight and then delete out of principle) CanJS will be smaller. We are in TodoMVC’s labs:

        http://addyosmani.github.com/todomvc/labs/
        https://github.com/addyosmani/todomvc/tree/master/labs/architecture-examples/canjs/jquery

        Check us out! We are smaller than Spine’s example, if I add a localStorage example …

        Spine Total, written in CoffeeScript with template = 150 LOC
        CanJS with template and some comments = 215 LOC – 75 (localStorage) = 140

        This is because of the live-binding. But it’s stupid to get into these games when the apps I write are 10ks of lines long.

        As far as meteor, which as far as I understand it polls over data to notice change, must scale terribly. What if you have a big record set? I think you might be attracted to what’s “cute”, the Justin Bieber of software. CanJS is a battle tested navy seal. (joking around here … thanks for the comments)

  • Loktar

    I’m quite new to pure js, so assuming this framework just uses classic MVC patterns, this tutorial was useful to me. It may lack comparison with others js frameworks, however there are plenty of articles with this concern …
    So no matter what more advanced js coders will say, I say thank you for the post ^^

  • http://nathanrjones.com Nathan Jones

    Does anyone have any comparison of this to backbone.js or agility.js?

  • https://github.com/js-coder Florian

    I think you forgot a couple of var statements in the contacts.js file? http://ccummings.github.com/canjs-contacts-tutorial/part1/js/contacts.js `Contact`, `Category` and `Contacts` are missing the var statement and thus become globals.

    • https://github.com/js-coder Florian

      I’ve looked a bit into Ember.js today and I saw that it’s the same there, the var statement is always omitted for classes. Can somebody explain to me why this is done? :)

  • Ian

    It’s always good for competition and to have alternative tools at your disposal. I find myself agreeing with the majority of the commenters on this post however in that with the sheer number of frameworks, libraries, and tools popping up on a daily basis having more thrown at you isn’t always helpful. Choosing what to spend your time learning and using on a regular basis is getting ever more important so if there is a tutorial or introduction to yet another tool which does exactly what a number of others do it would be useful to know how it compares to other popular tools and what problems it attempts to address which are lacking in the competition. Just running off in another direction to learn another tool just isn’t useful without the foundation as to why – although thanks to Jeremy for a very explanatory comment, that gives a better overview. :)

    If a blog like Nettuts advocates a tool by reviewing it or providing material on it then generally a lot of people are going to follow in that direction so I suppose there does come some responsibility in what is reviewed along with providing the reasons it may fit in particular situations.

    Personally with the rapid rise in popularity of the likes of backbone it would take a lot to shift me in another direction having invested time in learning it and it’s widespread adoption. I’d personally like to see tools which compliment it or enhance it when building javascript applications rather than try to replace it and encourage a back to the drawing board approach.

    • http://bitovi.com Justin Meyer

      Ian,
      Thanks for your comment. However, I don’t think there’s an expensive cost to learn CanJS from Backbone. Understanding the MVC approach is much more important. With that, you can port your knowledge to any other MVC library because there are so many similarities between the libraries. You would not be returning to the drawing board.

      If you’ve developed in your Backbone development far enough, you might understand some of the issues CanJS solves, especially preventing memory leaks through templated event binding and its non-leaking model store.

      A few more issues I’ll put out.

      can.Observe handles nested data. For example:

      o = new can.Observe({
      name : {first: “Brian”, last: “Meyer”}
      })
      o.bind(“first.name”, function(){…});
      o.attr(“first.name”,”Justin”);

      Model’s return deferreds, making a bunch of common Aync patterns much easier:

      $.when( Task.findAll(), Category.findAll() ).then(function(){

      })

      When a todo instance is destroyed it will be automatically removed from any model list that had it. This is sweet for live-binding. For example:

      Task.findAll({}, function(tasks){
      // render list
      can.view(“mytemplate.ejs”, tasks);

      //sometime later, remove the item, it’s removed from the list auto-magically
      setTimeout(function(){
      tasks[0].destroy();
      },1000)
      })

      It also has a lot of first party plugins that are pretty swell. My favorite is the jquery view modifiers, allowing you to load a template in parallel with its data and render it all in an awesome one-liner:

      $(“#tasks”).html(“tasks.ejs”, Task.findAll() );

      I’m also working on a can.route article that shows how the “observable” nature of can.route can keep routes out of view code, and handle setup / teardown with ease.

      So, if those few things can’t peak your interest, along with it’s performance, memory safety, size, and library-support, let me know what CAN … :-)

      • Ian

        Now THAT’s the kind of thing that would have been good to see in this post from the start. :) Every framework, library, and script has their own take on things which usually tries to address various problems in others. As an introductory or prequel post it could have been good to learn about the history of can.js along with what it aims to solve and how it could help if you’re already using frameworks of a similar nature. All of which you’ve done an excellent job in answering in your comments. It’s just that when you get introduced to a “new kind on the block” and get straight into the obligatory contacts manager example it doesn’t do anything to set it apart from what’s already out there and doesn’t really do much to peak the interest.

        In terms of templating, the parallel loading of data along with the template sounds interesting but I’d probably still prefer to use pre-compiled templates for performance and caching benefits. Does it provide option for that too or does this depend on the templating library used?

      • http://twitter.com/JacopKane Furkan Tunalı

        It’s not included but i guess you can use steal.js (from the same team) or localStorage

  • Fritz Lekschas

    I don’t get all the complains here. Isn’t it awesome and helpful enough to get a 3-parts tutorial for a new framework? Read it and you will find out if you like it or not. It’s as simple as that I would say :)

  • camus

    In the realms of Frameworks , in my opinion there are 2 main trends : libraries with independant components , and big monolitics libs that are “opiniated” (the ruby way ;) )about the way one should do things.

    While Backbone fits in the first category ,and in my opinion is more difficult to learn since there is not one way to do things and doesnt provides data binding out of the box ,CanJs seems to belong to the second one , which is a good thing , though some concepts like deffered , ect are difficult to grasp for beginners.

    Backbone has some momemtum right now because it relies on tool people already know jQuery , underscore which is some kind of prototype built the right way , etc … so its integration feels quite natural in existing projects. Furthermore it doesnt feel like a “black box” more like a set of abstract objects one has to extend with whatever methods one wants. Good luck to CanJS.

  • thecountofzero

    I’ve got to say that I am a bit surprised by some of the negative feedback I’ve read in some of the above comments. This was meant to be an introduction to a great framework for building JavaScript-based web applications. So, as an introduction, it is quite understandable and expected that much will be unanswered.
    Constructive criticism, questions and even doubts are a good thing.

    But to attempt to dismiss the efforts of others simply because other libraries/frameworks already exist seems a bit counter productive to me. I do understand the “great here’s another framework to learn” mentality as it seems that everyday there is something new I read about on nettuts, dailyjs or Twitter that makes me say “man I wish I had time to learn about that”. Unfortunately there just aren’t enough hours in the day to learn everything and have a life outside of the web application development world.

    Therefore it is up to each of us to decide what we feel is worth investigating. Those that left comments here obviously were interested enough to take the time to read the tutorial. And that’s a great start. But what are the next steps? I say learn more. Heck, this was only part one of three part introductory series. Find out if this thing is actually the real deal and if not, tell them why it isn’t.

    But just because you have already invested the time in learning Backbone and it has gained some good momentum should you say that any new framework is a waste of time or the wrong approach. Because quite honestly, while this part one of a three part introductory series may not have done CanJS justice, it would be near impossible to do so in such a short introduction. How many people would have read a two hour long tutorial?

    Take a little time and take a look at http://www.canjs.us and http://www.donejs.com before you jump to any conclusions. I was lucky enough to stumble upon JavaScriptMVC two years ago and have been playing with it since. So I have seen the transformation of the frameworks/tools which has been the result of a lot of hard work from the team of developers. These are are not only smart dudes, but also educators. Check out their forum. They answer nearly all the questions (quickly) and continually provide top-notch free support and insight into the how and why. These guys clearly care about the quality of their work and the impact it can and will have on everyone else.

    A marketing ploy??? Come on. What have they to gain? CanJS, DoneJS, JavaScriptMVC, Steal, etc all of the tools they provide are free to use. These guys are busting their asses to give the rest of the world the tools they need to develop kick-ass web apps. And to do so easily. Anyone who has been developing web apps for the last 10 years and can remember what a pain is was to do certain things a year ago, let alone 5, have got to appreciate the fruits of a framework like CanJS.

    Now I am not going to get into the CanJS is better than Backbone debate here (even though I think it is), but even had I never heard of CanJS until reading this tutorial, I would not dismiss that it could be just because Backbone has more cheerleaders.

    The only true way to find out for yourself is to get your hands dirty. Go ahead and play around with the live binding feature of CanJS and tell me you are not impressed. And while you’re there, give the rest of the framework a ride.

    I will say that I agree that I am not a fan of creating CanJS app’s as a single file. Even small ones. I realize why it is done here for the simplicity of the tutorial, but I think people like to see the clear separation of the MVC components. It’s great for a fiddle or a quick “here check this out”, but I don’t much like it for developing apps.

    Thanks for the tutorial. I am looking forward to the rest of this series and hopefully many more touching on the rest of the kick ass CanJS features.

    Yes you CAN!

  • Oscar Balladares.

    It is funny reading firsts comments. There is an (my) universal law that can be applied here:

    “The people who complains the most are those who know the less; because for them, everything is still hard”.

    I know people that can read an API in a few days and then start building amazing things in the next days. I wouldn’t say CanJS is messy, nor hard till I try to do something useful with it and find if it is hard/messy or not.

    Also, it is a bad bad manner to criticize something that is free for you guys.

    • Ian

      “The people who complains the most are those who know the less; because for them, everything is still hard”.

      Everything is hard when you’re learning it. Nettuts articles appeal to novice and professional developer alike each specialising in their own areas. If people are taking the time to read and learn something new then it’s going to be more difficult but that’s a good thing. Learning at every level is encouraged and necessary and depending on your background and previous experience getting to grips with something new could take hours or months. Criticism of those trying to learn is no better than criticism of the tools. A little understanding on both counts goes a long way.

  • http://www.imstillreallybored.com Josh Bedo

    Yeah this looks horrible for me as well.

  • http://borovin.com Andrew

    Unfortunately I do not know english well enough to describe all of my admiration for this framework. And I do not understand people who say “it looks horrible”. What are you talking about? MVC architecture plus live-binding within 8.5 kb.. Did you ever try to build a REAL js-application using these technologies? Any existing solutions weigh more and it does not have all these opportunities.. Thanks to the developers for “another solution” that has helped my career. I just told my boss: “Yes, I CAN”. =)

  • http://stepansuvorov.com/blog STEVER

    totaly agree with Andrew

  • patie

    Awesome framework.

  • Alfredo

    The only issue I’ve got following the tutorial is that I was using jquery 1.8.X, and it works only with jquery 1.7.X. But that is not a big deal.

    I think canJS is outstanding!

  • Nene

    The first part of this tutorial worked in only Firefox. It did not work in Opera 12.11 and Chrome 23.0. I dont know if it has to do with the templating.

  • Fergal

    I don’t get these templating / data binding libraries. Everything they can do I can easily achieve by building HTML as strings using plain JS or as elements using jQuery. Using data- attributes in elements to store any useful info about an element and when the time comes to do something just read the value of attributes.

    Why maintain JavaScript Objects that are then processed by a library to generate HTML? Why not just do that myself?

  • daslicht

    Is it possible to reuse can on the server side in Node?