can.compute
Create an observable value.
can.compute( getterSetter[, context] )
Create a compute that derives its value from can.Maps and other can.computes.
Parameters
-
getterSetter
{function(newVal, oldVal)}
A function that gets and optionally sets the value of the compute. When called with no parameters, getterSetter should return the current value of the compute. When called with a single parameter, getterSetter should arrange things so that the next read of the compute produces that value. This compute will automatically update its value when any observable values are read via attr.
-
context
{Object}
OptionalThe
this
to use when calling thegetterSetter
function.
Returns
{compute(newVal)}
A new compute.
can.compute( initialValue [, settings] )
Creates a compute from a value and optionally specifies how to read, update, and listen to changes in dependent values. This form of can.compute can be used to create a compute that derives its value from any source.
Parameters
-
initialValue
{*}
The initial value of the compute. If
settings
is not provided, the compute simply updates its value to whatever the first argument to the compute is.var age = can.compute(30); age() //-> 30 age(31) //-> fires a "change" event
-
settings
{Object}
OptionalConfigures all behaviors of the compute. The following cross binds an input element to a compute:
var input = document.getElementById("age") var value = can.compute("",{ get: function(){ return input.value; }, set: function(newVal){ input.value = newVal; }, on: function(updated){ input.addEventListener("change", updated, false); }, off: function(updated){ input.removeEventListener("change", updated, false); } })
Returns
{compute(newVal)}
The new compute.
can.compute( initialValue, setter(newVal,oldVal) )
Create a compute that has a setter that can adjust incoming new values.
var age = can.compute(6,function(newVal, oldVal){
if(!isNaN(+newVal)){
return +newVal;
} else {
return oldVal;
}
})
Parameters
-
initialValue
{*}
The initial value of the compute.
-
setter
{function(newVal, oldVal)}
A function that is called when a compute is called with an argument. The function is passed the first argumented passed to compute and the current value. If
set
returns a value, it is used to compare to the current value of the compute. Otherwise,get
is called to get the current value of the compute and that value is used to determine if the compute has changed values.
Returns
{compute(newVal)}
A new compute.
can.compute( object, propertyName [, eventName] )
Create a compute from an object's property value. This short-cut signature lets you create a compute on objects that have events that be listened to with can.bind.
var input = document.getElementById('age')
var age = can.compute(input,"value","change");
var me = new can.Map({name: "Justin"});
var name = can.compute(me,"name")
Parameters
-
object
{Object}
An object that either has a
bind
method or a has events dispatched on it via can.trigger. -
propertyName
{String}
The property value to read on
object
. The property will be read viaobject.attr(propertyName)
orobject[propertyame]
. -
eventName
=propertyName
{String}
OptionalSpecifies the event name to listen to on
object
forpropertyName
updates.
Returns
{compute(newVal)}
A new compute.
Use
can.compute
lets you make an observable value. Computes are similar to Observes, but they represent a single value rather than a collection of values.can.compute
returns a compute function that can be called to read and optionally update the compute's value.It's also possible to derive a compute's value from other computes, can.Maps, and can.Lists. When the derived values change, the compute's value will be automatically updated.
Use compute.bind to listen for changes of the compute's value.
Observing a value
The simplest way to use a compute is to have it store a single value, and to set it when that value needs to change:
Any value can be observed. The following creates a compute that holds an object and then changes it to an array.
Derived computes
If you use a compute that derives its value from properties of a can.Map or other can.computes, the compute will listen for changes in those properties and automatically recalculate itself, emitting a change event if its value changes.
The following example shows creating a
fullName
compute that derives its value from two properties on theperson
observe:Notice how the definition of the compute uses
attr
to read the values of the properties ofperson
. This is how the compute knows to listen for changes.Translator computes - computes that update their derived values
Sometimes you need a compute to be able to translate one value to another. For example, consider a widget that displays and allows you to update the progress in percent of a task. It accepts a compute with values between 0 and 100. But, our task observe has progress values between 0 and 1 like:
Use
can.compute( getterSetter )
to create a compute that updates itself when task'sprogress
changes, but can also update progress when the compute function is called with a value. For example:The following is a similar example that shows converting feet into meters and back:
Events
When a compute's value is changed, it emits a change event. You can listen for this change event by using
bind
to bind an event handler to the compute:Using computes to build Controls
It's a piece of cake to build a
can.Control
off of the value of a compute. And since computes are observable, it means that the view of that Control will update itself whenever the value of the compute updates. Here's a simple slider that works off of a compute:Now that's some delicious cake. More information on Controls can be found under
can.Control
. There is also a full explanation of can.Map'scompute
, which is used in the last line of the example above.