Skip to content

Instantly share code, notes, and snippets.

@justinbmeyer
Last active August 20, 2019 21:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinbmeyer/1e3206ae62c3c083db0aad2f1df46e4f to your computer and use it in GitHub Desktop.
Save justinbmeyer/1e3206ae62c3c083db0aad2f1df46e4f to your computer and use it in GitHub Desktop.

Easily build components

CanJS makes it really easy to build web components. Why easy:

A class-based, object oriented API

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.

No build required

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>

Powerful debugging

CanJS has extremely powerful debugging tools. Including:

  • The ability to trace exactly why a value changed:

  • The ability to see what values the DOM is reading:

  • The ability to see what values another value, or the DOM affect:

  • The ability to break when a value changes:

Useful documentation

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.

Scalable architecture

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(); 

Easily build CRUD apps

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.

Models make it easy to CRUD data

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();

Application Scaffolding <can-crud>

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:

Promises in templates

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 }}

Real-time list updating

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.

Longevity

Your application has a long future ahead of it. CanJS is a platform you can trust for the future.

Web component interoperability

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.

Backwards compatability (independent repos, codemods)

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.

Actively maintained for 10 years

Frontend technology changes rapidly. CanJS has provided an upgrade path to new tools and techniques for over 10 years.

Active Community

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment