steal/ - CanJS modules using the StealJS syntax (see [using-steal using with StealJS])

If you wish to use CanJS with jQuery, first load your jQuery library and then load CanJS with:

<script src="http://canjs.com/release/latest/can.jquery.js"></script>

How can we load CanJS using AMD / RequireJS?

The default library used with AMD modules is jQuery. CanJS will reference the jquery module so that name needs to point to your jQuery source and the can module name needs to be mapped to the amd/ folder of the CanJS download. In RequireJS a simple configuration looks like this:

You are set up and good to go. Follow up in the Using CanJS in production section on how to pre-compile your views and make a build using the RequireJS optimizer.

CanJS can pre-compile EJS and Mustache views into JavaScript functions contained within a single file in order to avoid additional requests for view files in production.

npm install can-compile -g

And in your project root folder run:

can-compile --out views.production.js

This will create views.production.js in the current folder containing all pre-compiled views. When loaded into your page CanJS will use the per-compiled views instead of making an Ajax request to retrieve them.

You can run the RequireJS optimizer against your application but need to make sure to put all the configuration in a separate file, e.g. js/app.js:

To use your pre-compile views with RequireJS just add a custom wrapper in the options that uses the AMD definition to load can/view/mustache and/or can/view/ejs (depending on what you are using). In a Grunt task:

To load the generated files only when running the RequireJS optimizer r.js define an empty module in development like:

define('views', function() {});

And require('views'); in your main application file. When running the optimizer map this module to the production build file:

paths: {
views: 'views.production'
}

Always make sure that the output file is in the same folder as the root level for the views that are being loaded. So if your CanJS applications HTML file is in the app folder within the current directory use a filename within that folder as the output file:

can-compile --out app/views.production.js --can 2.0.0

How can we scaffold a CanJS application using Yeoman?

npm install -g yo bower grunt generator-canjs
// Create the main application folder, go inside the main application folder,
// and generate the rest of the application's folder structures
mkdir canjs-app && cd canjs-app
yo canjs
// Install or add various dependencies
bower install -S bootstrap fontawesome
// Scaffold the user model.
// Creates the user.js file in the models folder.
// Model generator will offer to create fixtures for the generated model.
// The User model fixtures will be generated in the fixtures/users.js file.
yo canjs:model models/user
// Scaffold the user control.
// The canjs:control generator is different from the canjs:model generator.
// It doesn't create just one file. Instead, it creates a folder which contains
// all files needed to run this control in isolation.
yo canjs:control controls/users
// Watch for changes in files (in one terminal window)
grunt watch
// Start the server
grunt connect:server
// Compile JavaScript and view files to the production.js file
grunt build

The canjs:control generator is different from the canjs:model generator. It doesn't create just one file. Instead, it creates a folder which contains all files needed to run this control in isolation. If you run it like:

When you ran the app generator the style folder was created. Usually I use the style/style.less as the starting point for my CSS styles. First, let's set up Bootstrap and FontAwesome. Create the variables.less file in the style folder and copy the contents from the bower_components/bootstrap/less/variables.less in to that file.

Copy contents from the bower_components/bootstrap/less/bootstrap.less to style/style.less and adjust the paths for all the files except the variables.less file (we're loading that one from the style folder). Your style/style.less file should look something like this:

Bootstraping Bootstrap (yeah, I know :)) from the style/style.less file allows us to make changes to the styles in the isolation from the original Bootstrap code. This makes future upgrades of the Bootstrap library painless and simple.

App generator created two .html files in the project root. The canjs-app.html file and the production.html file. canjs-app.html file will be used for the development, as it loads the dev versions of all scripts, while the production.html loads only the built file.

We set up the base app structure, and now is the time to add support for the components. When developing CanJS apps, it is a good practice to develop each component in the complete isolation from the rest of the app. All of it's styles, templates and assets should be contained in one folder, ready for reusing. There is a problem with supporting the image and font paths in the CSS. We want our CSS to work the same in three different contexts:

App development and production mode are pretty much the same, but we have an issue with the component development mode since it will load the CSS from the different location. Thankfully, LESS compiler can rewrite urls in the build step, so we can get the correct urls in the built CSS. To take advantage of this, I recommend you to use the following technique:

Create style/components.less file and @import each component's LESS file from there

Import style/components.less file from the style/style.less file

Load the built 'style/style.css' file from the component's demo page (eg. components/users/users.html) as it will have the correct paths

can.fixture: The can.fixture dependency is special because, normally, you don't want it to be a part of your final application; however, it can be very helpful during development. can.fixture.js allows you to simulate RESTful services. You can download it here.

can.route: back button and bookmarking support. For many JavaScript MV* frameworks, routing divides an application into logical views and binds those views to Controllers. This is not how things work in CanJS. Routing in CanJS has nothing to do with binding views to Controllers. Rather, it has to do with AppState. In brief, CanJS maintains a reciprocal relationship between an application’s route and its state. In other words, if you change the state of an application, your route will change. If you change your route, your application’s state will change. This is a very powerful programming paradigm. For example, you can recreate a specific state in your application from any point, just by accessing a specific route.

can.Components: A can.Component is like a mini web application. It contains the JavaScript, CSS, and HTML necessary to create a fully functional item. This makes can.Component’s portable, reusable, and encapsulated. can.Component’s are easy to test and easy to use. Building an application with them is kind of like building with Lego™. The secret to building large applications is to never build large applications. Rather, you build the components you need and link them together using the Application State and Routing to compose your application.

Application State: An Application State object, or AppState object for short, is an observable object that, as its name implies, contains the state of your application.

What are the most important components in CanJS?

can.Observe: Observable objects provide a way for you to make changes to data and listen to those changes. Observables such as can.List and can.Map provide the foundation for updating model objects, views, and even routes in your app.

can.Construct: Many of the objects in CanJS are derived from can.Construct. Understanding it, therefore, will make it easier for you to understand other concepts. can.Construct provides a way to easily use the power of prototypal inheritance without worrying about hooking up all the particulars yourself.

How does CanJS handle memory leak?

Memory safety is really important, especially in long-lived, dynamic pages. CanJS combats this menace in two important and unique ways:

Controls that unbind event handlers auto-magically

A model store that does not leak

Controls that unbind event handlers auto-magically. Say you’re creating a tooltip widget that shows when you mouseover an element. You might use it like:

On mouseleave, the tooltip element is removed from the DOM. However, there is nothing to remove mouseleave event handler. The event handler reference the $el variable via a closure. Because, the mouseleave event handler is not removed, the tooltip element still exist in memory even though it had been removed from the DOM. As a matter of fact, every time the user mouseover the h1 tag, a new mouseleave event handler is created.

CanJS solves this with templated event handlers. Here’s that same tooltip with can.Control:

can.Control keeps a reference to all event handlers created for each control, listens for the control’s parent element to be removed, and unbinds all event handlers. Controls made with can.Control don’t leak.

CanJS’s tools are designed to work under almost every situation. Your server sends back XML with strange urls? That’s ok, overwrite can.Model.findAll or can.Model.models. Want some special teardown code for a control? Overwrite can.Control:destroy.

But our favorite bit of flexibility is how can.Observe works with nested data. It converts nested objects into observes automatically. For example:

Want to share code between a Zepto mobile app and a jQuery desktop app? No problem. CanJS code (especially models) can be shared across libraries, and so can skill sets! Working on a Dojo project today and a YUI one tomorrow? Don’t throw away all of your skills.

What is the view modifer plugin?

Deferred are simply awesome for handling asynchronous behavior. Models produces deferreds and can.view consumes them. With the view modifiers plugin, you can load a template and its data in parallel and render it into an element with:

Although can.ejs’s live-binding is super fast, setting up live data binding can be too slow in certain situations (like rendering a list of 1000 items). EJS’s live binding is opt-in. It only turns on if you are using the attr method. If the following template binds to a todo's name …

<li> <%= todo.attr('name') %> </li>

… the following doesn’t setup live-binding and renders much faster …

<li> <%= todo.name %> </li>

What is the purpose of can.stache?

can.stache contains utilities “for the loading, processing, rendering, and live-updating of templates”. In addition, can.stache is used to bind views to observable objects.

What is the first step in putting together a CanJS application?

The first step in putting together a CanJS app is sketching out the states of your application. I think that this is like planning out the pages and "components" that you will need. An state is like a stage (where the user is in the process of whatever the user is using your application for). For example, The order confirmation state shows the items the user selected, a total, and the personal information they’ve provided with the order. Note that this state also has a link to restart the ordering process, should the user want to place another order at the same restaurant.

The states can also be independent of each other. For example, the order history state can be access without having to actually place an order.

What is the purpose of the extend function that is part of can.Construct?

What is the purpose of can.Construct? How can we use can.Construct to create our own objects and extend our own objects? How many parameters can the extend function accept? How will the extend function behave if we pass it only one argument? How will the extend function behave if we pass it only 2 arguments? How will the extend function behave if we pass it 3 arguments?

can.Construct’s extend function is used to create “constructor functions”. Constructor functions create instances of objects. The extend function can take up to three arguments:

name: string

staticProperties: object

instanceProperties: object

The extend function behaves differently depending on the number of arguments you pass it. If you pass it one argument, it will use the value you pass it to set its instanceProperties. If you pass it two arguments, it uses the first to set its staticProperties and the second to set its instanceProperties. If you pass in all three arguments, the first will set its name, the second its staticProperties, and the third its instanceProperties.

This pattern will apply to all objects in CanJS that have an extend function. For example, if we only want to set staticProperties we must call the function as follows:

This example is highlighted because calling a can.Construct with two parameters, the last of which is an empty object, is common. Also common is the mistake of ommitting the last parameter of the call, which can lead to unexpected behavior.

What is the purpose of the init function that is part of can.Construct?

The init function is called whenever a new instance of a can.Construct is created. init is where the bulk of your initialization code should go. Inside of the init function, the this keyword will refer to the new object instance created by the constructor. Additionaly, this will contain the instance properties you pass to the constructor. A common thing to do in init is save the arguments passed into the constructor. An example is below:

Observables are the subjects in the observer pattern. They let you create relationships between objects where one object (or objects) listens for and responds to changes in another object. Most of the core objects in CanJS are observables. Understanding how to effectively work with observables lies at the heart of understanding how to build successful CanJS applications.

can.Map and can.List are often extended to create observable types. For example, can.Model and can.route are based on can.Map, and a can.Component’s viewModel is a can.Map.

How can we create a can.Map object?

To create a Map, call new can.Map(object). This will give you a map with the same properties and values as the object you passed in to the can.Map constructor.

The difference is that now you can use other can.List's function to work with this list.

What is the purpose of the attr function that is part of can.Map, can.List or other can.Observe objects?

The attr method is used to read a property from, or write a property to a can.Map or can.List. While you can read the properties of a can.Map or can.List directly off of the object, to take advantage of the observable functionality you must use the .attr syntax.

What events are triggered when an attribute is changed for a can.Map object?

When a property on a Map is changed with attr, the Map will emit two events: A change event and an event with the same name as the property that was changed.

What are the two methods to listen for events on a can.Observe object?

When a property on a Map is changed with attr, the Map will emit two events: A change event and an event with the same name as the property that was changed. There are two ways you can listen for these events:

can.List inherits from can.Map. A can.List works much the same way a can.Map does, with the addition of methods useful for working with arrays:

indexOf: looks for an item in a List.

pop: removes the last item from a List.

push: adds an item to the end of a List.

shift: removes the first item from a List.

unshift: adds an item to the front of a List.

splice: removes and inserts items anywhere in a List.

When these methods are used to modify a List events are emitted that you can listen for, as well. See the API for Lists for more information.

How can we create the AppState object?

CanJS suggests using a global appState object to manage the state of your application. The appState object is bound to two things:

The application’s base template

The application’s routing

Since you already know about creating instances of can.Map, creating an appState object, which is a can.Map, will be easy. Let’s see how this works. Open up your app.js file and update it as shown below.

It was mentioned earlier that we bound our AppState to the application’s main.stache. This is the key to connecting the AppState to our components. Because the appState object is bound to our main template, which includes the rest of the components in the app, these attributes will automatically be included in the scope of the components.

What is the purpose of can.Component?

A can.Component is like a self-contained, mini web application; in other words, it’s encapsulated. Because can.Component’s are encapsulated, they should each contain their own:

View template file (.stache file)

JavaScript file

CSS file

This is why we created a components folder for our app—instead of, say, a js folder. Each component we develop will be in a folder that contains all the files that support that component. This makes components portable, enabling you to reuse them across projects. It also isolates them, making them easier to test and maintain.

How can we create a can.Component?

Put the following code inside components/restaurant_list/restaurant_list.js:

Notice that the above code define 3 things: a viewModel, a template, and a tag 'pmo-restaurant-list'. The tag property associates that can.Component with a specific, custom HTML tag. We will talk about tag a bit more further down below.

Put the following code to components/restaurant_list/restaurant_list.stache:

<h1>{{currentRestaurant}}</h1>

Finally, we need to add a reference to components/restaurant_list/restaurant_list.js in the index.html file:

<script src="components/restaurant_list/restaurant_list.js"></script>

Now, go back out to your app in the browser and refresh it. On the Restaurants page, you should see it printing: "Hello Restaurant Customer".

What is special about the extend method of can.Component?

Whenever you declare an object using can.Construct, it must be instantiated. Normally, you would either directly instantiate objects using the new keyword, or pass the constructor to an object that would create instances of it. can.Component is an exception.

All we have to do is declare the can.Component using its extend function. The extend function register your component with CanJS. When CanJS parses the main.stache file and encounters the custom tag defined by this component, it will automatically instantiate this component, generate the component’s view inside of its custom tag, and bind that view to your component’s scope.

What is a view model?

The viewModel object is the can.Component’s view model. The view model is an abstraction of the view that exposes public properties and functions. Any property or function defined on the view model object is available from the can.Component’s template as either a Stache data key, or a function. In our example above, we created the property currentRestaurant and then referenced it as a Stache data key in our template.

Perhaps the viewModel object is the context object for Handlebars (or the view object for Mustache).

Can we use the define plugin with the viewModel object of a can.Component?

Yes. can.List, can.Map, and other can.Observe objects can be the base class for other objects, and can be used for any purpose (there is really no limitation or restriction). In this case, if you wish to use a can.Map object as the viewModel object, you can. In fact, it is recommended:

Here we’re using the define plugin to set up the following properties:

state: to keep track of the selected state

states: with the list of states that can be selected

city: capture the name of the city that’s selected

citiesByState: an object that has the list of cities by state name

cities: which is the list of cities for the selected state

In the state setter, we’re showing an alert when a new state is selected. If you refresh the Restaurants page, you should see a select element with the states as options; when you select a state, an alert will appear with the selected state’s name.

How can we set or get properties of the viewModel object?

Getting and setting are done through the attr function of the viewModel object, in this case this is bound to the scope, because we’re within a method of the scope. In the above example, we use the define plugin. We need to understand the define plugin a bit more. Anyway, getting and setting are done through the attr function of the viewModel object.

How can we have good readability and maintainability?

It’s considered a best practice to keep your can.Components thin. This helps with having good readability and maintainability. To accomplish this, you extract your scope from the can.Component into a can.Map:

Because it is a can.Construct, can.Model.extend can take up to three parameters:

name

staticProperties

instanceProperties

A can.Model’s staticProperties parameter has several reserved properties you can add that simplify accessing data from a JSON REST service. These properties are:

findAll

findOne

create

update

destroy

The find*, create, update, and destroy functions are available directly off of the object definition (i.e., they are static). The destroy function is available off of specific instances of a can.Model.

Reminder: The number of parameters you pass in to an extend function is important. If you pass in a single parameter object, the extend function will use that to set the instanceProperties. If you pass in two parameter objects, the first object passed in will be used to set the staticProperties. The second parameter will be used to set the instanceProperties. Here, we only want to set the staticProperties, so we must pass in a second, empty object.

Perhaps, this is not mandate by CanJS. Perhaps, these can take a JSON object. Notice that in the first example above, findAll is not defined as a function.

How can we use can.fixture?

CanJS provides a handy utility, can.fixture, that we can use to easily mimic the functionality of connecting to a server. can.fixture intercepts an AJAX request and simulates a server response with a file or a function. You can use can.fixture to develop JavaScript independently of backend services.

can.fixture is not included with the base CanJS package. It’s a good practice to keep it separate from your production CanJS library, which is why we downloaded and used it a separate script tag, rather than including it with our custom download. If you use can.fixture during development, remember to remove it once you need to connect to your REST services.

Add the following code to the models/fixtures.js file:

can.fixture('GET /api/states', 'models/states.json');

The first argument to can.fixture, GET /api/states, tells CanJS to intercept any GET requests to the resource /api/states. The second argument is a path to a file with the data the fixture will return. Because we’re simulating a findAll function, we need to return an array. The findAll function expects an array. By default, if it does not receive one, it will throw an error. If you need to connect to services that return data that doesn’t match the expected return type of the find* functions, don’t fret. There are ways to manage this, which we’ll work with later on.

Let’s also create a fixture that will respond to our requests for the list of cities for each state. This one is going to be a little different because we want to be able to return a different list depending on which state is included in the request. Thankfully, can.fixture is flexible and allows you to dynamically respond to requests. Let’s add the following code to the models/fixtures.js file:

The first argument to can.fixture, GET /api/cities, is similar to our restaurants example: we’re setting up this fixture to intercept any GET requests to /api/cities. The second argument, however, is different: it is a function that returns the data we want to get when the application makes a service call. In our example, we’re making an AJAX request (via can.ajax) to get the fixture data from a JSON file, then responding to the request with the data we fetched.

How can we connect our data model to our view model?

Open up components/restaurant_list/restaurant_list.js, find the states property:

You can remove the citiesByState property since we won’t be using it anymore. Let’s also update the components/restaurant_list/restaurant_list.stache file to match the changes we made in the view model. The most significant change is that our cities and states properties now return a promise instead of just an array. Find the form element:

You’ll notice the {{#if restaurants.isPending}} and {{#if restaurants.isResolved}} lines; the first is for showing a loading indicator while the restaurants are being loaded, and the second is for showing the list of restaurants once they’ve been fetched from the server (or in our case, from the fixtures). After they have, {{#each restaurants.value}} iterates over the list of restaurants to show them on the page.

The first argument to can.fixture, GET /api/states, tells CanJS to intercept any GET requests to the resource /api/states. The second argument is a path to a file with the data the fixture will return.

Let’s also create a fixture that will respond to our requests for the list of cities for each state. This one is going to be a little different because we want to be able to return a different list depending on which state is included in the request. Thankfully, can.fixture is flexible and allows you to dynamically respond to requests. Let’s add the following code to the models/fixtures.js file:

The first argument to can.fixture, GET /api/cities, is similar to our restaurants example: we’re setting up this fixture to intercept any GET requests to /api/cities. The second argument, however, is different: it is a function that returns the data we want to get when the application makes a service call. In our example, we’re making an AJAX request (via can.ajax) to get the fixture data from a JSON file, then responding to the request with the data we fetched.

Because can.fixture intercept the AJAX calls, the above can.ajax is really returning a fixture. We can use this trick if we need to return different fixtures for different circumstance, but how does this work? Perhaps, can.fixture automatically invoke the function with appropriate request and response objects so that we can inspect those to form appropriate URL, and let can.fixture intercept the can.ajax call, and let the can.ajax call mechanism works. The success function is nothing special. It is just the regular success function that are part of can.ajax.

Notice the <input /> element with a (keyup) event handler. Whenever there is a keyup event in the input, the code in the value will be executed. We’re also passing @element.val to the setPhoneValue helper. Let’s add the component’s JavaScript to the components/order_phone/order_phone.js file:

Notice that the error property uses this.attr("order").attr("phone") in its getter. Because of CanJS’s observables, CanJS is aware of us setting that value in our setPhoneValue helper, and thus only runs the getter again (called “recomputing the value”) when the value has changed. When the setPhoneValue helper sets the value, CanJS recomputes the error property’s value, which will return an error if you type “911” or anything that doesn’t look like a phone number.

Note that you can place as many event handlers as you need on an element. Adding event handlers in this way directly binds the events to the element. This can impact performance in situations where you have many elements to bind events to. For more performant event binding, you can use the can.Component’s events property.

the second sets the saveStatus property on the component’s view model to whatever the save method on the order object returns, and

the third line returns false to stop the form element’s default submission behavior.

Let’s look at a few items in the code above. Unlike data access functions (e.g., findAll, findOne), which are called statically off of the prototype, the save, update, and delete functions are called off of a specific instance of a model. So, if we want to create a new order, we will need to work with an instance of the Order model.

To provide fixture support for saving our can.Model, open up models/fixtures.js and add the following fixture:

Here, you can see that we’re implementing the save functionality by responding to POST requests to /api/orders with the original request data, plus an _id property. We also added support for GET requests to /api/orders so we can provide order history functionality.

What does can.Model allow us to do / What is the purpose of can.Model?

In CanJS, can.Model adds functionality to can.Map to work with data on a server. It enables you to:

Using any server with a REST interface, can.Model enables create, read, update, and destroy a resource.

How does CanJS implement data driven controls?

The "data driven control" term refers to developing application controls such that changes in the data / state automatically update the UI. In CanJS, using can.Mustache, data driven controls are structured with the following architecture:

Event handlers in the UI controls strictly maintain and update the UI state objects.

The control update the state, which trigger the change event handler within the template engine, which automatically update the DOM. The reason for this approach is simplicity. You only worry about how to represent your data once, while creating your template (and associated helpers). Set it and forget it. Any time data or state changes, those changes are automatically reflected.

When you push the todo, the DOM will reflect the change automatically. A few concrete advantages of doing things this way are:

There’s no need for selector strings in your UI code. These have a tendency to change often, breaking brittle selector strings.

Enforces strict separation between template and control logic. Previously, writing a Control required intimate knowledge of the DOM structure and rules connecting the state to the DOM. Code like this is harder to read and maintain. With live binding, the template (or helpers) contain all of this logic. The Control just maintains application logic.

The performance will be much better, compared to the “Render Everything” example above. can.Mustache renders just the smallest portion of the template that is required. If a todo is pushed, a single LI will be created and appended to the UL.

When you use this pattern yourself, there are a few rules to live by:

No DOM manipulation code in the control (except template helpers)

Render templates only once (during control initialization)

Connect complex state to the DOM with a Mustache helper

1. No DOM manipulation code in the control (except template helpers). This includes adding classes! For example, imagine you need to keep track of the currently “active” todo. If you set the className directly in the control, you’ll have to query the DOM to figure out which todo is active (or worse, keep track of this information twice). This is bad!

Instead, keep track of state on the data itself, and use Mustache helpers to tie that state to the DOM. In this example:

2. Render templates only once (during control initialization). Avoid re-rendering templates. Pre-live binding, the pattern was to render the control template each time something changed. The pattern now is to render templates in your init method, only once, like this:

init: function(){
this.element.html(renderTemplate(data));
}

3. Connect complex state to the DOM with a Mustache helper. Any attributes accessed with the attr method in a Mustache helper will set up a live binding, so translate any non-trivial state logic to the DOM with helpers like: