Migrating to 0.8

Many of these migration notes are cribbed from the CHANGELOG. While we strive to minimise breaking changes, and to highlight the ones we do introduce, if you discover an undocumented breaking change please .

Migrating from 0.7.x

What's new

Ractive's data handling has been completely rewritten to use a full viewmodel hierarchy as opposed to the previous hashmap-like implementation. This has made the code much easier to reason about, and it should also eliminate many data-related bugs. It also has made large swaths of Ractive considerably faster.

Spread arguments (...arguments) and arguments access is now available for method event handlers. Individual arguments are available using array notation (arguments[n]), dot notation (arguments.0), or 1-based dollar vars, like regular expression matches ($1, $2, etc).

There is now support for linking data to extra keypaths in the model. This is particularly handy for master-detail scenarios where you have a complex list of objects and you want to focus on a single one at a time. A keypath like 'foo.bar.bazzes.0' can be linked to 'baz' so that the detail section doesn't have to worry about a non-bindable expressions or copying objects around. Both sides of the link are automatically kept in sync. See ractive.link().

You can now use ES2015 object literal shorthand in templates e.g. { foo } is equivalent to { foo: foo }.

If you have object keys with .s in them, you can now escape them with a \. So if you have a bar object with a foo.baz property, it can be accessed with bar.foo\.baz. Keypaths in the template are given as escaped paths so that they can be used directly with Ractive methods. There are also a few new static methods on Ractive to deal with escaping, unescaping, splitting, and joining keypaths.

<textarea>s now handle HTML content as plain text to match what happens in browsers. They can now also set up two-way binding with a single interpolator as content instead of using the value attribute e.g. <textarea>{{someBinding}}</textarea> is equivalent to <textarea value="{{someBinding}}"></textarea>.

Progressive enhancement is now supported with a few limitations. If you pass enhance: true when creating your Ractive instance, it will not discard the contents of its target element and will instead try to reuse elements and nodes as it builds the virtual DOM from its template. This option is incompatible with the append option.

The Object, String, and Boolean globals are now accessible from within templates.

You can now set up aliases with context and iterative mustache sections that can be used to clarify templates and avoid issues with object-literal context sections and two-way binding. For context sections, use {{#with someExpressionOrRef as alias1, some.deeply.nested[reference].expression as alias2}}...{{/with}} to set up as many aliases as you need. For iterative sections, you can alias the context with the iteration (the current item) by using {{#each some.list as item}}...{{/each}}. Partial contexts also support aliasing, since partial context is just a shortcut for {{#with context}}{{>partial}}{{/with}}, as {{>somePartial some.path as alias1, some.other[expression](arg1, arg2) as alias2}}.

There is a new CSP-compatible parsing mode that collects all of the expressions in the template at the end of the parse and stores them as functions on the template root. At render-time, any expressions look for a corresponding pre-built function before using new Function(...) to create one. Templates parsed in this way are no longer JSON compatible. To enable this mode, pass csp: true when pre-parsing your template.

If your environment supports it, you can now use Unicode characters from the Supplementary Multilingual Plane and the Supplemental Idiographic Plane in your templates.

There are two new special references available on your templates for access to the current Ractive instance and your environment's global object. @this will resolve to the nearest Ractive instance in the template, which includes components should the template belong to one. @global resolves to window in most browsers and global in Node.js. Both special references are also available outside of the template so that Ractive can be notified of changes outside the template easily.

Keywords can now be used as references, so you can now use new, if, while, etc as references.

Keypaths within components are now adjusted to be relative to the component. If you need to access the path to the data relative to the root instance, you can use the new special reference @rootpath.

Partials defined in <script> tags can now contain top-level inline partial definitions that will get added to the instance along with the scripte-defined partial.

You can now retrieve the CSS for a Ractive instance with a new toCSS method. You can also get the CSS for all instances with a new static Ractive method of the same name.

You can now trigger a transition with ractive.transition( transition, node, options ), and node can be supplied implicitly from an event handler. Transitions can now return a Promise and complete will automatically be called when the promise resolves.

Class and style attributes now get special treatment that keeps them from clobbering external changes. There are also special attribute forms for targeting a single class or inline style at a time using e.g. style-left="{{x}}px" and class-someClass="{{someCondition || someOtherCondition}}". For the special style form, additional hyphens in the attribute are turned into camel case. For the special class form, the truthiness of the value determines whether or not the class is added to the list.

As set will create intermediate objects when setting an undefined keypath, array methods will now swap in an empty array instead of erroring when called with an undefined keypath. Trying to use an array method with a non-array value including null will still throw.

Event objects created by event directives and the results of Ractive.getNodeInfo() are now enhanced with a number of contextual helper methods to make interacting with Ractive in template-relative contexts programmatically easier. The old node info object properties are now deprecated, and their functionality has been replaced by the resolve and get methods.

Transitioning elements will not longer keep unrelated elements from being removed. Transitions now have a safety check that forces them to complete within a short interval from their target duration, which keeps misbehaving transitions and browsers from causing elements to get stuck in the DOM.

elseif and else blocks no longer include previous blocks' conditions in their own, so expensive computations are no longer repeated and conditions for elseif are no longer forced to be an expression. Instead, subordinate blocks connect with their siblings when they render and only show if all prior siblings have falsey conditions.

merge can now be called with the same array that exists at the given keypath, and the differences will be computed from the model's cached array members. This allows extensive in-place modification of an array to be handled as a series of splice operations but in a single operation. Note that merge may be moved to a set option at some pooint in the future.

Breaking changes and deprecation

Migrating from 0.6.x

What's new

Components can now access their parents and containers using an official API.

Binding directives may be set on elements that support two-way binding. These directives override the settings on the Ractive instance for twoway and lazy.

Single-fire versions of ractive.on and ractive.observe are now available as ractive.once and ractive.observeOnce.

Inline partials can now be defined within a new section {{#partial partial-name}}...{{/partial}}. The old comment syntax is now deprecated and will be removed in a future release.

Inline partials are now scoped to their nearest element. If a partial reference sits in the template below an element with a matching inline partial, the inline partial will be used in the reference. This can be used as a sort of partial inheritance. If an inline partial is defined directly within a component tag or the root of the template, it will be added to the Ractive instance.

Components may now yield to multiple inline partials by supplying the partial name with yield e.g. {{yield some-name}}. Yielding without a name will still result in non-partial content being yielded. Only inline partials may be yielded. Any partials, including inline and inherited, may still be referenced within a component using a plain partial section e.g. {{>partial}}.

Partials can now be reset without resorting to manually un/re-rendering them using a wrapping conditional section. This can be done with the new resetPartial method on Ractive instances.

this.event is now available to method-call event handlers.

Regular expression literals can now be used in template expressions.

You can now escape mustaches with a '\' if you'd like them to appear in the template.

ractive.toggle now works with patterns.

The debug setting is no longer set per-instance. It has been replaced with Ractive.DEBUG, which defaults to true. You can set it automatically based on whether or not the your code has been minified with:

Ractive.DEBUG = /unminified/.test(function(){/*unminified*/});

Breaking changes and deprecation

Migrating from 0.5.x

Lifecycle events

Ractive instances now emit lifecycle events. If you use Ractive.extend(...) with init(), beforeInit() or complete(), you will need to replace them - they will continue to work, but will be removed in a future version.

init() can be replaced with one of the following methods, or you may need to split your code into both methods. Use onrender() for code that needs access to the rendered DOM, but is safe being called more than once if you unrender and rerender your ractive instance. Use oninit() for code that should run only once or needs to be run regardless of whether the ractive instance is rendered into the DOM.

The init() method also no longer recieves an options parameter as the ractive instance now inherits all options passed to the constructor. You can still access the options directly using the onconstruct() method.

beforeInit() and complete() can be replaced directly with onconstruct() and oncomplete() respectively.

See the lifecycle events page for more detail.

Other Breaking changes

Migrating from 0.4.x

Breaking changes