Skip to content
This repository has been archived by the owner on May 15, 2023. It is now read-only.

ConstraintJS Internals

Stephen Oney edited this page Dec 29, 2013 · 18 revisions

ConstraintJS automatically detects and manages dependencies between constraint variables.

For instance, if y is declared as:

y = x.add(1);  // y <- x + 1

Then a dependency from x to y is established, which is illustrated conceptually with an arrow from x to y:

![y depends on x](http://cjs.from.so/tutorial/images/x_to_y_dependency.png)

y depends on x (think of x's value as flowing to y)

This dependency lets ConstraintJS know that whenever `x` changes, `y` should also change. When we call:
x.set(9)

y and any other variables that depend on x are marked as invalid, which means that their values needs to be recomputed:

![y is invalidated after x changes](http://cjs.from.so/tutorial/images/x_to_invalid_y.png)

y is invalidated after x changes

The .invalidate() function can be used to manually invalidate a variable (.set() automatically invalidates its value).

ConstraintJS uses a "pull model" for constraints, meaning that y is only recomputed when its value is requested; not as soon as it's invalidated. When y's value is valid, ConstraintJS caches its value so that it isn't recomputed unnecessarily. To illustrate, consider the following snippet of code, where although x's value changes three times, y's value is only recomputed twice:

var y = cjs.constraint(function() {
    console.log("recomputing y");
    return x.get() + 1;   // y <- x + 1
});
        
x.get();   // = 2
y.get();   // = 3, "recomputing y" printed
y.get();   // = 3, nothing printed
x.set(9);  // x <- 9
x.set(10); // x <- 10
x.set(11); // x <- 11
y.get();   // = 12, "recomputing y" printed

For the curious, this academic paper contains more in-depth details on ConstraintJS's inner mechanics.


Next: DOM Bindings

Previous: Constraint Variables

Clone this wiki locally