Virtual DOM Implementation with Ractive

Preface

For various reasons, I desired to have the change-efficiency of a virtual DOM without the ReactJS management. There is a standalone virtual DOM implementation, but it leaves the management up to you. I found that Ractive could be used as a minimal manager for a DOM section.

Abstract

Use a lodash template as the generator for a DOM section, to be applied through Ractive’s virtual DOM diff operations

Details

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Create a ractive managed DOM structure with some data and html generater
### ex:
ractive = virtual_dom
el$:'.tickets'
generater:Template['campaign/ticket.html']
data:{ordered: 'yep, ordered', id:123}})
###
site.virtual_dom = (options)->
ractive = new Ractive
el: options.el$
template: Template['component/pass.mu']()
data:
generater: options.generater
data: options.data

notes:

  • We provide a options.el$ as a selector, to select an element present within the actual DOM, such as #virtualDomHere
  • Template['component/pass.mu'] represents a minimal mustache template serving as a passthru for the generater function
  • The generater function could be a lodash template

pass.mu

1
{{{ generater({data:data}) }}}

campaign/ticket.html

1
2
3
<div class="single_item ticket" data-id="<%= data.id %>">
<%- data.ordered %>
</div>

Notes

The data would then necessarily be managed through the ractive instance.

Extra

Preface

If data sets are held in the front end, I prefer to hold them in a front end database. ForerunnerDb is excellent for this. So, let’s explore using this virtual DOM in such a way that reacts to changes within a collection

Abstract

Use a ForerunnerDb collection as the data store that ractive reacts to

Details

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Create a ractive managed DOM structure with some db collection, data_getter, and html generater
### ex:
ractive = virtual_dom_db
el$:'.tickets'
generater:Template['campaign/ticket.html']
collection: collection
data_getter:((collection)-> collection.find({}))
###
site.virtual_dom_db = (options)->
ractive = new Ractive
el: options.el$
template: Template['component/pass.mu']()
data:
generater: options.generater
data: options.data_getter(options.collection)
options.collection.on "change", ()->
ractive.set 'data', options.data_getter(options.collection)
ractive

notes:

  • the data_getter represents, perhaps, a way of ordering or filtering the data from a collection that is to be shown
  • the collection is the ForerunnerDb collection (example presented below)

collection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fdb = new ForerunnerDB
db = fdb.db("site")
collection = db.collection("test_collection")
collection.deferredCalls(false)
# Filling the collection with misc data using chance.js
generate_inserts = ()->
for i in [1..50]
_id: i
age: chance.age()
name: chance.name()
phone: chance.phone()
country: chance.country()
joined: chance.date()
zip: chance.zip()
cc: chance.cc()
collection.insert generate_inserts()