Add declarative data-binding

This commit is contained in:
Jeremy Likness 2019-11-27 14:26:18 -08:00
parent 5a5fe8123e
commit 2ea7049dd2
3 changed files with 45 additions and 24 deletions

View File

@ -71,6 +71,30 @@ export class DataBinding {
}; };
} }
/**
*
* @param {HTMLElement} elem The parent element
* @param {object} context The context to use for binding
*/
bindAll(elem, context) {
this.bindLists(elem, context);
this.bindObservables(elem, context);
}
/**
* Searches for "data-bind" attribute to data-bind observables
* @param {HTMLElement} elem The parent element to search
* @param {object} context The context to use for binding
*/
bindObservables(elem, context) {
const dataBinding = elem.querySelectorAll("[data-bind]");
dataBinding.forEach(elem => {
this.bindValue(
/** @type {HTMLInputElement} */(elem),
context[elem.getAttribute("data-bind")]);
});
}
/** /**
* Searches for "repeat" attribute to data-bind lists * Searches for "repeat" attribute to data-bind lists
* @param {HTMLElement} elem The parent element to search * @param {HTMLElement} elem The parent element to search

View File

@ -1,6 +1,6 @@
// @ts-check // @ts-check
import {DataBinding} from "./dataBinding.js" import { DataBinding } from "./dataBinding.js"
/** /**
* Represents a slide * Represents a slide
@ -21,7 +21,7 @@ export class Slide {
* Context for embedded scripts * Context for embedded scripts
* @type {object} * @type {object}
*/ */
this._context = {}; this._context = { };
/** /**
* Data binding helper * Data binding helper
* @type {DataBinding} * @type {DataBinding}
@ -66,7 +66,7 @@ export class Slide {
const script = this._html.querySelector("script"); const script = this._html.querySelector("script");
if (script) { if (script) {
this._dataBinding.executeInContext(script.innerText, this._context, true); this._dataBinding.executeInContext(script.innerText, this._context, true);
this._dataBinding.bindLists(this._html, this._context); this._dataBinding.bindAll(this._html, this._context);
} }
} }

View File

@ -1,30 +1,27 @@
<title>Data-Binding Example 1</title> <title>Data-Binding Example 1</title>
<h1>Data-Binding Example</h1> <h1>Data-Binding Example</h1>
<label for="first"><div>Number:</div><input type="text" id="first"/></label> <label for="first"><div>Number:</div><input type="text" id="first" data-bind="n1"/></label>
<label for="second"><div>Multiplied by Number:</div><input type="text" id="second"/></label> <label for="second"><div>Multiplied by Number:</div><input type="text" id="second" data-bind="n2"/></label>
<label for="result"><div>Result:</div><input type="text" id="result" disabled/></label> <label for="result"><div>Result:</div><input type="text" id="result" data-bind="result" disabled/></label>
<label for="firstName"><div>First Name:</div><input type="text" id="firstName"/></label> <label for="firstName"><div>First Name:</div><input type="text" id="firstName" data-bind="first"/></label>
<label for="lastName"><div>Last Name:</div><input type="text" id="lastName"/></label> <label for="lastName"><div>Last Name:</div><input type="text" id="lastName" data-bind="last"/></label>
<label for="fullName"><div>Full Name:</div><input type="text" id="fullName" disabled/></label> <label for="fullName"><div>Full Name:</div><input type="text" id="fullName" data-bind="full" disabled/></label>
<br/> <br/>
<ul> <ul>
<li repeat="list" class="appear">{{item.idx}} &mdash; {{item.value}}</li> <li repeat="list" class="appear">{{item.idx}} &mdash; {{item.value}}</li>
</ul> </ul>
<script> <script>
this.list = [{idx: 0, value:"one"}, {idx: 1, value:"two"}, {idx: 2, value:"three"}]; this.list = [{idx: 0, value:"one"}, {idx: 1, value:"two"}, {idx: 2, value:"three"}];
const bindings = () => { const first = this.observable("Jeremy");
var n1 = this.observable(2); const last = this.observable("");
var n2 = this.observable(2); const n1 = this.observable(2);
var result = this.computed(() => n1.value*n2.value, [n1, n2]); const n2 = this.observable(4);
var first = this.observable("Jeremy"); // assign to context
var last = this.observable(""); this.n1 = n1;
var full = this.computed(() => `${first.value} ${last.value}`.trim(), [first, last]); this.n2 = n2;
this.bindValue(document.getElementById("first"), n1); this.first = first;
this.bindValue(document.getElementById("second"), n2); this.last = last;
this.bindValue(document.getElementById("result"), result); // computed
this.bindValue(document.getElementById("firstName"), first); this.result = this.computed(() => n1.value*n2.value, [n1, n2]);
this.bindValue(document.getElementById("lastName"), last); this.full = this.computed(() => `${first.value} ${last.value}`.trim(), [first, last]);
this.bindValue(document.getElementById("fullName"), full);
};
setTimeout(bindings, 0);
</script> </script>