0.0.6 • Published 5 years ago

@dweomercraft/elementalism v0.0.6

Weekly downloads
1
License
ISC
Repository
github
Last release
5 years ago

Elementalism v0.0.6

Non-polling dom observation and two-way data binding

Install

npm install @dweomercraft/elementalism

Example

A working example can be downloaded here: https://github.com/dweomercraft/elementalism-example

How it works

Elementalism creates wrappers around individual nodes, including all of their prototype methods and properties. Prototypes are not directly inherited. The wrapper integrates an event system that triggers when the wrapper modifies the element. Thus, the obvious caveat here is that changes to the element must be performed by the wrapper, and not the element itself or other elements around it.

Usage

Observing an element in the dom and subscribing to changes

// some.html
<div id="el">bar</div>

// some.js
const Elementalism = require('@dweomercraft/elementalism');

const em = new Elementalism();

// Create an Elemental wrapper around the element
const elemental = em.getElementalById('el');

// Subscribe to any updates in the elemental
elemental.on('update', (changes) => {
    if ( changes.children ) {
        if ( changes.children.add ) console.log('childnodes added');
        if ( changes.children.update ) console.log('childnodes updated');
        if ( change.children.remove ) console.log('childnodes removed');
    }
    if ( changes.attribute ) {
        if ( changes.attribute.add ) console.log('attribute added');
        if ( changes.attribute.update ) console.log('attribute updated');
        if ( changes.attribute.remove ) console.log('attribute removed');
    }
    if ( changes.remove ) console.log('removed from dom');
});

// Subscribe to the usual dom events through the elemental
elemental.on('click', () => {
    console.log('clicked');
})

const node = document.createElement('div');
elemental.appendChild(node); // childnodes added
elemental.innerHTML = 'Change triggered'; // childnodes added, childnodes removed

elemental.setAttribute('id', 'bar') // attribute added
elemental.setAttribute('class', 'foobar') // attribute updated

elemental.click() // clicked

elemental.remove() // removed from dom

Setting up two-way data binding

// some.html
<div id="parent">
    <span data-model="foo">foo</span>
    <input type="text" data-model="hello" value="world">
</div>

// some.js
const em = new Elementalism();

/**
 * At initialization, an elemental will check its children for any data-model
 * attributes and bind the corresponding value as a property to its model.
 */
const parent = em.getElementalById('parent');
/**
 * Internally binds foo and hello to its model:
 * parent.model.foo = bar
 * parent.model.hello = world
 */

parent.on('update', (changes) => {
    if ( changes.children ) {
        if ( changes.children.add ) console.log('childnodes added');
        if ( changes.children.update ) console.log('childnodes updated');
        if ( change.children.remove ) console.log('childnodes removed');
    }
});

// Create a child Elemental
const foo = em.querySelectorAll(parent.element, '[data-model="foo"]')[0];
// Modify the view through the child elemental
foo.innerHTML = 'foobar'; // childnodes updated  ('update' event was propagated up to parent)

// Modify the model
parent.model.foo = 'bar'; // childnodes updated

// Alternatively if the element has the value attribute
const helloNode = em.querySelectorAll(parent.element, '[data-model="hello"]')[0];
helloNode.value = 'example' // childnodes updated

Docs

class Elementalism constructor(config) config (Object) - properties: global (Boolean) - Default: true, shares a cache of elementals to reference with other global instances Properties elementals (Elemental[]) - Returns an array of registered Elementals signatures (String[]) - Returns an array of signatures. Signatures are automatically generated when an Elemental object is created. An element's signature is also stored in its data-signature attribute. collection (Collection) - Returns the collection of signature-elemental pairs Methods invoke(elements, handler) - Creates or retrieves Elementals for each element. Registers the handler to each element's change event. Returns an array of Elementals. elements (NodeList|Element) handler (UpdateHandler) getElementalBySignature(signature) - Returns an Elemental associated with the signature signature (String) getElementalById(id) - Searches the document for an element with a matching id. Creates or retrieves an Elemental for the resulting element. Returns the Elemental. id (String) getElementalsByClassName(root,classname) - Searches the root for any elements matching the classname. Creates or retrieves Elementals for the resulting elements. Returns an array of Elementals. root (Element) classname (String) getElementalsByTagName(root, tag) - Searches the root for any elements matching the tag. Creates or retrieves Elementals for the resulting elements. Returns an array of Elementals. root (Element) tag (String) querySelectorAll(root, selector) - Searches the root for any elements matching the selector. Creates or retrieves Elementals for the resulting elements. Returns an array of Elementals. root (Element) selector (String) class Elemental constructor(element) element (Element) Properties element (Element) - Returns the element associated with the Elemental Methods synchronize(param) Synchronizes the view with the model and emits any changes that occurred during synchronization param (Object)

  • model (String) - Instructs the method to synchronize provided model property with the view

addEventListener(event, handler) Registers an event handler to the event event (String) handler (Function) on(event, handler) - Wrapper for addEventListener() onChange(handler) - Registers the provided handler to the change event handler (UpdateHandler) Function UpdateHandler(updates) updates (UpdateObject) Object UpdateObject - Object emitted by the change event Properties children (Object)

  • add (Array) - Contains elements added to the Elemental
  • remove (Array) - Contains elements removed from the Elemental

attribute (Object)

  • add (Object) - Contains attribute-value pairs of newly added attributes
  • update (Object) - Contains attribute-{value, oldValue} pairs of updated attributes
  • remove (Object) - Contains attribute-value pairs of removed attributes

remove (Boolean) - Elemental's element has been removed from the dom

Version Log


v0.0.6

  • Elementals can now perform two-way data binding by adding a data-model attribute to any children elements in its dom tree.
  • Elemental children now propagate their synchronization callbacks up to their parent elemental
  • Elementals now append a unique signature to every child element
  • 'update' event now has a children.update property if any child nodes were modified

v0.0.5

  • Fixed read me typos

v0.0.4

  • Elementals now emit an 'update' event rather than a 'change' event to avoid overlap with the InputElement's change event

v0.0.3

  • Fixed a check that tried referencing a nonexistent variable

v0.0.2

  • Combined children, attribute, and remove events into a singular 'change' event
  • Elementalism dom queries will create Elemental wrappers for any matches that don't have a wrapper.
  • invoke() accepts a function to be passed to each element as a change event handler

v0.0.1

  • Fixed a bug when resolving attribute changes