<pacem-data> is the observable box of a page: park a value in its model, bind to it from anywhere, and every binding follows along.
No script, no store: it's your ViewModel, written in markup.
<!-- a plain value -->
<pacem-data id="quantity" model="1"></pacem-data>
<!-- an entity, kept across reloads -->
<pacem-data id="user" model="{ name: 'Ada', age: 36 }" persist-as="my-user"></pacem-data>
Seed it. The model attribute is evaluated as JavaScript, so literals come out typed: "0" is a number, "[1, 2]" an array, "{ a: 1 }" an object.
Use a binding instead and the model becomes derived: it follows whatever it's bound to.
<pacem-data id="total" model="{{ #cart.model.length }}"></pacem-data>
Read it from any binding, nested paths included: {{ #user.model.name }}.
Write it from a handler, a two-way binding or plain code:
<pacem-button on-click="#quantity.model++">+</pacem-button>
<pacem-input-text value="{{ #user.model.name, twoway }}"></pacem-input-text>
Change notifications fire when
modelgets assigned. Editing inside it from a handler (#user.model.name = 'Grace') changes the data, but nobody gets told: replace the model instead. Two exceptions notify on your behalf: two-way bindings on nested paths, and the mutating methods (push,splice,pop…) of an array that is the model (not of one nested in it).
<pacem-button on-click="#user.model = { ...#user.model, name: 'Grace' }">rename</pacem-button>
Persist it. persist-as="key" saves the model to local storage on every change and restores it on load.
Assigning null removes the stored entry; changing the key drops the old one.
Calm it down. A chatty source (a slider, typing, a stream) can flood its dependents.
debounce holds the notifications back: a number of milliseconds, or true for once per animation frame.
Add throttle="true" to notify the first change of each window and drop the others.
Throttling drops, it doesn't delay: the last change of a burst may never be notified. When the final value matters, debounce.
React to it. Every notification is a propertychange event, so on-propertychange runs side effects:
<pacem-data model="{{ #search.value }}" debounce="300" on-propertychange="#results.fetch()"></pacem-data>
Two-way bound fields edit a persisted entity. Type something, then reload the page.
One source, three listeners: count how many notifications each one lets through while you type fast.
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.