Observe your JavaScript objects


What is Iota Observable?

And how does it compare to other projects?

Iota Observable is a tiny library written in the programming language CoffeeScript. It offers functions to create observable objects and make existing objects observable. Its primary use case is to be employed as part of a view layer with declarative data-binding in a JavaScript single page app. Because CoffeeScript compiles to JavaScript, you can use it with JavaScript as well.

Iota Observable has been designed to play nicely with Rivets, a little template engine with declarative data binding from Michael Richards. Both libraries strive to "do one thing and do it well". They leave everything else to your choice — a modular approach. You might want to give the Rivets & Iota Observable combo a chance if you feel that AngularJS, EmberJS, Knockout, Batman etc. are too invasive and big for your use case.

Features

what makes it special

Nested properties

dot notation

Navigate the object graph using the dot notation: model.get('person.address.name'). It doesn't matter whether the nested objects are observable or not.

Computed properties

automatic dependency tracking

Properties can be derived from other properties, simply by making them no-arg functions. If you use the get and set functions and another property is changed, observers are automatically notified about changes in the computed property: get('a') + get('b').

Batch updates

for better performance

You can set multiple properties at once by passing an object to the set function. You can also demarcate a series of updates with beginBatch and endBatch. Observers which would be notified multiple times when doing separate updates, are triggered only once that way.

Browser support

compatibility

Successfully tested in Internet Explorer 8, latest Chrome and latest Firefox.

Getting started

Usage

because some lines of code often say more than 1000 words

Basics (CoffeeScript)

# Extend from Observable
class Person extends Observable
  constructor: (@firstName, @lastName) ->
    super()
    
  name: -> 
    @get('firstName') + ' ' + @get('lastName')

# Create a person
obj = new Person 'Bela', 'Bartók'

# Query initial value of name (normally done by view)
console.log 'Initial name: ' + obj.get('name')

# Register observer
obj.on 'name', -> console.log("Name has changed")

# Change property value, prints "Name has changed"
obj.set 'firstName', 'Béla'
Complete example

Basics (JavaScript)

// Extend from Observable
var Person = function(firstName, lastName) {
  Observable.call(this);
  this.firstName = firstName;
  this.lastName = lastName;
};
Person.prototype = Object.create(Observable.prototype);
Person.prototype.name = function() {
  return this.get('firstName') + ' ' + 
      this.get('lastName');
};

// Create a person
var obj = new Person("Bela", "Bartók");

// Query initial value of name (normally done by view)
console.log('Initial name: ' + obj.get('name'));

// Register observer
obj.on('name', function() {
  return console.log("Name has changed");
});

// Change property value, prints "Name has changed"
obj.set('firstName', 'Béla');

With Rivets (CoffeeScript)

Needs Rivets Iota Observable Adapter. This particular example code also needs jQuery.

# Create counter object and make it Observable
model =
  counter:
    value: 5
    
Observable.makeObservable model.counter

# Bind counter value to a DOM element
template = '<div data-text="counter.value" />'
domElement = $(template)[0]
rivets.bind(domElement, model)

# Append DOM element to main tree
$(domElement).appendTo "body"

With Rivets (JavaScript)

Needs Rivets Iota Observable Adapter. This particular example code also needs jQuery.

// Create counter object and make it Observable
var model = {
  counter: {
    value: 0
  }
};
Observable.makeObservable(model.counter);

// Bind counter value to a DOM element
var template = '<div data-text="counter.value" />';
var domElement = $(template)[0];
rivets.bind(domElement, model);

// Append DOM element to main tree
$(domElement).appendTo("body");
Complete example

Resources

get it

Download

Please note that this is only the top-level JavaScript file. It doesn't contain dependencies. I strongly recommend you to use a build tool with automatic dependency resolution (like Volo or npm). If you want to manage dependencies yourself, please see the list of dependencies in the modules section.

Install

  • This is the preferred approach for usage in the Browser because it scales very well in modular JS development. You need an AMD module loader like RequireJS.

    1. If you use Volo, just type in shell:
      volo add iota-observable
      If not, download the JS file and the required dependencies listed in the modules section manually.
    2. JavaScript:
      define(function(require) {
        var Observable = require('iota-observable');
        // ...
      Require optional modules as needed.
  • If you prefer old-fashioned globals, proceed like this:

    1. Download the JS file and the required dependencies listed in the modules section manually.
    2. Include the JS file(s) in your HTML file using script tag(s):
      <script src="iota-observable.js"></script>
    1. Shell:
      npm install iota-observable
    2. JavaScript:
      var Observable = require('iota-observable');

Development

Contribute

  • If you want to report an issue or suggest a feature, please do it in the GitHub issues section.
  • If you want to provide a fix or improvement, please fork Iota Observable and send me a pull request on GitHub. Thank you!
  • If you want to give general feedback, please do it in the forum.
  • If you want to show appreciation for the project, please "star" it on GitHub. That helps me setting my priorities.

Contributors

  • Benjamin Klum

Build

  1. Find the GitHub project of the module that you want to build by following the corresponding link in the modules section. Check out the sources from there. Some modules are so simple that they don't need to be built at all. For all others, proceed further.
  2. Install the module's runtime and development dependencies using npm:
    npm install
  3. Build the module and execute tests using Grunt:
    grunt

Credits

Credits go to ...

Changelog

1.0.0 2013-04-17 JS | GitHub
  • Initial release

Roadmap

1.x
  • Throttled observer invocation

Modules

Most of my projects are developed in a modular fashion. That means they are made up by several modules which can be used independently. Here's the list of the modules that make up the latest version of Iota Observable.

Name Required Version Download
iota-observable yes 1.0.0 JS
rivets-iota-observable-adapter no 1.0.0 JS