Decorators

If you've worked through the tutorials in order to this point, you may have wondered if there's some sort of hook to let you modify an element as it's created. Well, wonder no more!

Decorators are plugins, somewhat like custom events and transitions, that are attached to individual elements using a decorator directive. A decorator typically adds some sort of behavior to an element - makes it act like something - the decorator directive begins with as- and the decorator name.

Step 1

Starting with something simple, let's make a decorator that tracks certain nodes to which we want a direct reference. First, here's what a decorator looks like:

function tracked ( node, ...args ) {
  // do stuff with node
  // `this` is the Ractive instance

  // return a control handle
  return {
    // called when decorator args change
    function update () {},

    // undo stuff with node
    function teardown () {}
  }
}

There's not a whole lot going on there. When the decorator is called, it can do whatever it needs to with the node and return a control handle that lets Ractive tell it when arguments change or tear it down when the node is being unrendered. All we need to do is take an id argument, create a nodes hash on the Ractive instance if there's not already once there, and store the node at the given id. Fill in the missing code and then add decorator directive to the second div.

<div as-tracked="'special-div'">I am the special div.</div>

Then throw a manual style setting at the end of the script just to show everything worked:

ractive.node['special-div'].style.color = 'blue';

While that example is a bit contrived, you can probably see the benefit of using decorators when integrating with third party libraries that focus on adding functionality to a single node, like CodeMirror and Ace editor - in fact, the editors in the playground are handled by an Ace editor decorator.

Step 2

// TODO: formatting decorator