CanJS
CanJS is a lightweight, modern JavaScript MVVM (Model-View-View-Model) framework which is quick and easy to use while remaining robust and extensible to power some of the most trafficked websites in the world. This article will walk you through about CanJS and why you should use CanJS.
GET STARTED WITH CANJS
CanJS is a developing and improving set of client-side JavaScript architectural libraries which balances innovation and stability. It targets experienced developers, building complex applications with long future ahead. CanJS’s major aim is to reduce the cost of building and maintaining JavaScript applications by balancing innovation and stability, helping the developers to achieve a changing technology landscape.
The developer shouldn’t have to rewrite the application to keep pace with technology. CanJS aims to provide a stable and innovative platform, so the developer can block out the noise and stay focused on their applications, but not on the tools.
EVERY CANJS APPLICATION CONTAINS
- Observables
- Models
- ViewModels
- Views
- Custom elements and
- Routing with an AppViewModel
OBSERVABLES
Observable objects provide a way for the developer to make changes to the data. Observables such as can.The list, can.Map, and can.compute provides the foundation for models, view-models, view bindings, and also for routing in the developer’s app. can.compute is able to combine observable values into new observable values.
var info = can.compute(function(){
return person.attr(“first”)+” “+person.attr(“last”)+
” likes “+ hobbies.join(“, “)+”.”;
});
MODELS
Models let the developer to modify the data from the server. They also hydrate raw, serialized service data into more useful (and observable) type data on the client side. can.Model makes it easy to connect to restful services and perform Create, Retrieve, Update, and Delete the operations.
VIEWMODELS
ViewModels contains the state and model data used by the views to create HTML. They also contain methods that views can call.
VIEWS
Views are passed to a view-model and generate a visual output that’s meaningful to a user. Views are able to:
- Listen to the changes in view-models and update the HTML (one-way bindings).
- Listen to the HTML events, such as clicks, and call methods on the view-models and models (event bindings).
- Listen to the form elements changing and update view-model and model data (two-way bindings).
CUSTOM ELEMENTS
Custom HTML Elements are for how CanJS encapsulates and orchestrates different pieces of functionality within an application. Custom elements are built with the can.Component and combines a view-model and view.
ROUTING WITH AN APPVIEWMODEL
CanJS maintains a reciprocal relationship between the browser’s URL and a can.Map view-model. This view-model represents the state of the application as a whole and so is called the appViewModel. When the URL changes, CanJS will update the properties of the appViewModel. When the appViewModel changes, CanJS will update the URL.
WHY CANJS?
CanJS is designed to be a very well-rounded JavaScript framework which is useful to any client-side JavaScript team.
It provides a wealth of JavaScript utilities that combines to make a testable and repeatable Model-View-ViewModel application with very little code.
FLEXIBLE
CanJS is flexible. Unlike other frameworks, it’s designed to work in any situation. The developer can readily use third party plugins to modify the DOM with jQuery directly and uses alternate DOM libraries like Zepto and Dojo. CanJS supports all the browsers including IE8.
POWERFUL
CanJS is powerful. It creates the custom elements with one and two-way bindings. It easily defines the behavior of observable objects and their derived values. It avoids memory leaks with smart model stores and smart event binding.
SIMPLE EXAMPLE OF CANJS
The below code explains a simple template with events.
HTML
<script id=”user-welcomer-template” type=”text/stache”>
{{#with selectedUser}}
<welcome-message>
<h2>Welcome {{name}}!</h2>
</welcome-message>
{{/with}}
{{#users}}
<label>
<input name=”user” type=”radio” {{#isSelected .}}checked{{/isSelected}} {{data ‘user’}}><span>{{name}}</span>
</label>
{{/users}}
</script>
<script id=”welcome-message-template” type=”text/stache”>
<span><content></content></span><i class=”icon”></i>
</script>
var info = can.compute(function(){
return person.attr(“first”)+” “+person.attr(“last”)+
” likes “+ hobbies.join(“, “)+”.”;
});
CSS
label {
display: block;
margin: 1em;
cursor: pointer;
}
JS
var WelcomeMessage = can.Component.extend({
tag: “welcome-message”,
template: can.stache($(“#welcome-message-template”).text()),
});
var UserWelcomer = can.Component.extend({
tag: “user-welcomer”,
template: can.stache($(“#user-welcomer-template”).text()),
scope: {
chooseUser: function(scope, ev, user) {
console.log(scope, ev, user);
}
},
events: {
“:radio change”: function(el, e, val) {
this.scope.attr(‘selectedUser’, el.data(‘user’));
},
“init”: function() {
var scope = this.scope;
var users = scope.attr(‘users’);
var firstUser = users.attr(0);
scope.attr(‘selectedUser’, firstUser);
}
},
helpers: {
“isSelected”: function(user, options) {
if (this.attr(‘selectedUser’) === user) {
return options.fn(this);
}
return options.inverse(this);
}
}
});
var users = new can.List([
{name: ‘Tina Fey’, id: 1},
{name: ‘Sarah Alexander’, id: 2},
{name: ‘Anna Ferris’, id: 3},
{ name: ‘Leslie Mann’, id: 4},
{name: ‘Kristen Wiig’, id: 5 }
]);
var template = can.stache(”);
var frag = template({
users: users
});
$(‘body’).append(frag);