Ivy

IvyAttr(value, parseFn)

Creates an attribute. Attributes are the core of Ivy, they are observable through the on listener. Ivy attributes implement both valueOf and toJSON, so they can usually be used like JavaScript primitives.

var a = Ivy.attr(4),
    b = Ivy.attr(5);

console.log(a+b); //=> 9

An optional parseFn may be passed in to help parse values:

 var c = Ivy.attr("7", Number)
 c.valueOf(); //=> 7

IvyAttr.prototype.set(value)

Sets the internal value of the attribute, and emits a change event with the new value and the old value as the arguments.

IvyAttr.prototype.get()

Gets the internal value of the attribute.

IvyAttr.prototype.on(event, fn)

Adds a listener fn to the attribute that will trigger on event. The most common event is change.

var a = Ivy.attr(4);
a.on('change', function(value,oldValue){ 
  console.log('New value is', value, 'old value was', oldValue); 
});

a.set(5); //=> 'New value is 5 old value was 4'

IvyAttr.prototype.off(event, fn)

When given only an event type, stops all listeners for that event. If fn is given, only that callback will be removed.

IvyAttr.prototype.emit(event)

Emits a named event. Any additional arguements will be passed to the listeners.

IvyAttr.prototype.valueOf()

valueOf will return the attribute's internal value, this is useful when doing simple operations on attributes:

Ivy.attr(4) + Ivy.attr(5); //=> 9
Ivy.attr('Hello') + ' World'; //=> 'Hello World'

Be careful when testing boolean conditions:

Ivy.attr(false) ? 'true' : 'false' //=> 'true'

IvyAttr.prototype.toJSON()

toJSON will be called before JSON.stringify is called. This lets you easily serialize Ivy attributes:

var point = {x: Ivy.attr(3), y: Ivy.attr(7)};
console.log(JSON.stringify(point)); //=> {"x":3,"y":7}

IvyAttr.prototype.toString()

toString will call toString on the attribute's interval value:

var name = Ivy.attr('Wally');
console.log(name); //=> "Wally"

IvyArray(array)

An IvyArray supports emits events like a normal attribute, but has special methods for adding and removing array elements.

var array = Ivy.array([2,3,4]);
array.get(1); //=> 3
array.get(); //=> [2,3,4]

IvyArray.prototype.set(index, item)

Sets either the entire array to a new value, or a specific array element:

var array = Ivy.array();
array.set([2,3,4]);
array.set(1, "Hello");
array.get(); //=> [2,"Hello",4]

IvyArray.prototype.get(index)

Gets either the array or an item at the given index.

IvyArray.prototype.push(item)

Pushes an item onto the end of the array.

var array = Ivy.array([1,2,3]);
array.push(4);
array.get(); //=> [1,2,3,4]

IvyArray.prototype.unshift(item)

Pushes an item onto the front of the array.

var array = Ivy.array([1,2,3]);
array.unshift(4);
array.get(); //=> [4,1,2,3]

IvyArray.prototype.pop()

Pops an item off the end of the array, and returns it.

var array = Ivy.array([1,2,3]);
array.pop(); //=> 3
array.get(); //=> [1,2]

IvyArray.prototype.shift()

Shifts an item off the front of the array, and returns it.

var array = Ivy.array([1,2,3]);
array.shift(); //=> 1
array.get(); //=> [2,3]

IvyArray.prototype.replace(array)

Replaces the array contents with a new array.

var array = Ivy.array([1,2,3]);
array.replace([4,5,6]);
array.get(); //=> [4,5,6]

IvyArray.prototype.remove(item)

Removes an item from the array, and returns it.

var array = Ivy.array(["a", "b", "c"]);
array.remove("b");
array.get(); //=> ["a", "c"]

IvyArray.prototype.removeEach(fn)

Removes any item from the array that matches the function fn.

var array = Ivy.array([1,2,3,4,5]);
array.removeEach(function(i){ return i % 2; });
array.get(); //=> [1,3,5]

Returns an array of the items removed. The order of the items is should not be relied upon.

IvyArray.prototype.removeIndex(index)

Removes an item at a given index, and returns it.

var array = Ivy.array(["a", "b", "c"]);
array.removeIndex(1);
array.get(); //=> ["a", "c"]

Returns the removed item if any.

IvyArray.prototype.onEach(event, callback, getter)

Registers a callback for event on each array item as it is added, and unregisters listeners when items are removed from the array.

A getter function can be used to bind to events on an object's properties.

function Todo(name){
  this.name = Ivy.attr(name);
  this.isDone = Ivy.attr(false);
}

var todos = Ivy.array();
todos.onEach('change', function(isDone){
  console.log('Done state is now', isDone)
}, function(todo){ return todo.isDone });

todos.push(new Todo('Do something great!'));
todos.get(0).isDone.set(true); //=> 'Done state changed'

IvyArray.prototype.length()

Returns the length of the internal array.

IvyWrap(attr, wrapper)

Wrap an existing Ivy attribue, attr, with a wrapper providing custom getters and setters.

The original attribute can still be accessed as normal.

var percent = Ivy.attr(0.1);
var wrapped = Ivy.wrap(percent, {
  get: function(num){ return (num * 100) + '%'; },
  set: function(val){ return parseFloat(val) / 100; }
});

wrapped.get(); //=> "10%"
wrapped.set("17%");
percent.get(); //=> 0.17

Use this to decorate attributes for display.

IvyWrap.prototype.get()

Gets the internal attribute's value, then passes it through the custom getter.

IvyWrap.prototype.set(value)

Passes the value through the custom setter, then sets the internal attribute's value.

Ivy.fn()

Creates an computed attribute that is bound to its arguments. If an argument changes, the function will be recomputed.

var price   = Ivy.attr(15),
    tax     = Ivy.attr(0.1),
    withTax = Ivy.fn(price, tax, function(p,t){
      return p * (1 + t);
    });

withTax.get(); //=> 16.5
tax.set(0.05);
withTax.get(); //=> 15.75

The first arguments are the arguments the function depends on, the last is the function to be called. A bound Ivy attribute will be returned.

Ivy.fnWith(context, fn)

Like Ivy.fn, this creates a bound attribute, but the function binds to the variables named in the function.

function Purchase(price){
  this.price = Ivy.attr(price);
  this.tax   = Ivy.attr(0.1);
  this.withTax = Ivy.fnWith(this, function(price, tax){
    return price * (1 + tax);
  });
}

var purchase = new Purchase(15);
purchase.withTax.get(); //=> 16.5
purchase.tax.set(0.5);
purchase.withTax.get(); //=> 15.75

When working with complex objects, this is often simpler than using Ivy.fn.

This function does some clever stuff, so be careful if you use it with a minifier.

Object API

Documentation

Examples

Code