CanJS makes it really easy to build web components. Why easy:
CanJS has a class-based, Object Oriented API:
class MyCounter extends StacheElement {
static view = `
Count: {{this.count}}.
<button on:click="this.increment()">+1</button>
`;
constructor(){
super();
this.count = 0;
}
increment(){
this.count++;
}
}
Notice:
- Just extend the
StacheElement
class. - Create properties and methods like you would expect.
CanJS "just works" in modern browsers. There's no need for babel. Simply put your custom element in the page,
import StacheElement
and define your custom elements:
<my-counter></my-counter>
<script type="module">
import {StacheElement} from "http://canjs.com/core.mjs";
class MyCounter extends StacheElement {
static view = `
Count: {{this.count}}.
<button on:click="this.increment()">+1</button>
`;
constructor(){
super();
this.count = 0;
}
increment(){
this.count++;
}
}
customElements.define("my-counter", MyCounter);
</script>
CanJS has extremely powerful debugging tools. Including:
CanJS has comprehensive documentation. It has both guide & task-based documentation, and low-level API docs. Also most of it's examples can be immediately run in codepen, making experimentation easy.
Often you need to get something working, then make sure it works perfect, hence the expression: "Make it work, make it right". Also, applications are often developed by a wide variety of skill sets and experiences. There's also a lot of "easy" stuff to build, and a few places that have complex logic.
CanJS is design to scale to meet these needs.
First, it has a simple, imperative, Object-Oriented style of programming that looks just like normal class-based JavaScript programming:
class MyCounter extends StacheElement {
static view = `
Count: {{this.count}}.
<button on:click="this.increment()">+1</button>
`;
constructor(){
super();
this.count = 0;
}
increment(){
this.count++;
}
}
But you can incrementally make things more strict.
And incrementally make things more rigorous:
class StrictInput extends StacheElement {
static view = `<input value:bind="this.value"/>`;
static props = {
value: {type: String},
valueChangeCount: {
value(resolve, listenTo){
var changeCount = resolve(0);
listenTo("value", () => resolve(++changeCount) );
}
}
}
}
And easily testable.
let myCounter = new MyCounter();
myCounter.count //-> 0
myCounter.increment();
myCounter.count //-> 1
myCounter.render();
myCounter.firstElementChild.innerHTML //-> "1"
myCounter.connect();
90% of most applications are basic CRUD applications. Apps where you list records, and then have interfaces for creating, updating, and deleting those records. CanJS specializes in making this easy.
CanJS has models that make it easy to create, read, update and delete data.
class Todo extends ObservableObject {
static props = {
id: {type: Number, identity: true},
name: String,
dueDate: Date,
complete: false
}
}
const Todo = realtimeRestModel("/api/todos/{id}", Todo)
/* READ */
Todo.getList() //-> [todo, ...]
/* CREATE */
new Todo({}).save()
/* UPDATE */
todo.save();
/* DESTROY */
todo.destroy();
CanJS has scaffolding that automatically generates a UI to CRUD your data.
Simply add <can-crud>
to your page and give it a model type as follows:
<can-crud id="app"></can-crud>
<script>
import {ObservableObject, restModel, Crud} from "http://canjs.com/core.mjs";
class Todo extends ObservableObject {
static props = {
id: {type: Number, identity: true},
name: String,
dueDate: Date,
complete: false
}
}
const Todo = restModel("/api/todos/{id}", Todo);
customElements.define("can-crud", Crud);
app.ModelType = Todo;
</script>
And you get:
CanJS’s stache templating language can directly read the state and values from Promises. There's no need to write any extra code to determine whether a Promise is pending, resolved, or rejected.
{{# if(this.promise.isPending) }}
Loading…
{{/ if }}
{{# if(this.promise.isRejected) }}
Error: {{ this.promise.reason }}
{{/ if }}
{{# if(this.promise.isResolved) }}
Result: {{ this.promise.value }}
{{/ if }}
After data is created, updated, or destroyed, CanJS automatically updates your lists for you.
Filtering and sorting are preserved, so you don’t have to manually update your lists or fetch the same data again.
Your application has a long future ahead of it. CanJS is a platform you can trust for the future.
CanJS builds native web components. Native web components can be used by any framework. If you build functionality in CanJS, it will always be useful, no matter what happens to your codebase.
CanJS takes backwards compatability very seriously. It does this with:
- Independent Repos - CanJS builds everything in independent repos. This allows us to maintain legacy APIs far after they have been deprecated and removed from the "core" CanJS build. This allows you to upgrade to newer versions of CanJS with ease.
- CodeMods - We release scripts that update your app to the latest version, changing your code in-place.
Frontend technology changes rapidly. CanJS has provided an upgrade path to new tools and techniques for over 10 years.
While tiny compared to other frameworks, CanJS, being backed by Bitovi, has a very active community, with real people waiting to help you on slack or on our forums.