Add data-binding for lists

This commit is contained in:
Jeremy Likness 2019-11-25 16:46:59 -08:00
parent a4ae68dfb8
commit 0cab33efe5
5 changed files with 55 additions and 3 deletions

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="DevNexus presentation Vanilla.js: Modern 1st Party JavaScript"> <meta name="description" content="DevNexus presentation Vanilla.js: Modern 1st Party JavaScript">
<meta http-equiv="Content-Security-Policy" <meta http-equiv="Content-Security-Policy"
content="default-src 'self'; child-src 'none'; connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; media-src 'self'; object-src 'none'; style-src 'self';"> content="default-src 'self'; script-src 'self' 'unsafe-eval'; child-src 'none'; connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; media-src 'self'; object-src 'none'; style-src 'self';">
<link rel="shortcut icon" href="/images/logo.png" type="image/png" /> <link rel="shortcut icon" href="/images/logo.png" type="image/png" />
<link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/animations.css"> <link rel="stylesheet" href="css/animations.css">
@ -16,7 +16,7 @@
<body> <body>
<script type="module" src="./js/app.js"></script> <script type="module" src="./js/app.js"></script>
<slide-deck id="main" start="001-title"> <slide-deck id="main" start="data-binding">
<h1>DevNexus | Vanilla.js: Modern 1st Party JavaScript</h1> <h1>DevNexus | Vanilla.js: Modern 1st Party JavaScript</h1>
<h2>Setting things up ...</h2> <h2>Setting things up ...</h2>
</slide-deck> </slide-deck>

3
js/controls.js vendored
View File

@ -85,6 +85,9 @@ export class Controls extends HTMLElement {
* Enables/disables buttons and updates position based on index in the deck * Enables/disables buttons and updates position based on index in the deck
*/ */
refreshState() { refreshState() {
if (this._controlRef == null) {
return;
}
const next = this._deck.hasNext; const next = this._deck.hasNext;
const prev = this._deck.hasPrevious; const prev = this._deck.hasPrevious;
this._controlRef.first.disabled = !prev; this._controlRef.first.disabled = !prev;

View File

@ -14,6 +14,11 @@ export class Slide {
* @type {string} * @type {string}
*/ */
this._text = text; this._text = text;
/**
* Context for embedded scripts
* @type {object}
*/
this._context = {};
/** /**
* The HTML DOM hosting the slide contents * The HTML DOM hosting the slide contents
* @type {HTMLDivElement} * @type {HTMLDivElement}
@ -49,6 +54,42 @@ export class Slide {
else { else {
this._nextSlideName = null; this._nextSlideName = null;
} }
// execute any scripts
const script = this._html.querySelector("script");
if (script) {
(function (/** @type {string} */src) {
return eval(src)
}).call(this._context, script.innerText);
this.dataBind();
}
}
/**
* Scans for data-binding and applies the bindings
*/
dataBind() {
const listBinding = this._html.querySelectorAll("[repeat]");
listBinding.forEach(elem => {
const parent = elem.parentElement;
const expression = elem.getAttribute("repeat");
elem.removeAttribute("repeat");
const template = elem.outerHTML;
parent.removeChild(elem);
this._context[expression].forEach(item => {
let newTemplate = `${template}`;
const matches = newTemplate.match(/\{\{([^\}]*?)\}\}/g);
if (matches) {
matches.forEach(match => {
match = match.replace("{{", "").replace("}}", "");
const value = (function (/** @type {string} */src) {
return eval(src)
}).call({ item }, match);
newTemplate = newTemplate.replace(`{{${match}}}`, value);
});
parent.innerHTML += newTemplate;
}
});
});
} }
/** /**

View File

@ -2,4 +2,4 @@
<h1>I'm Not Anti-Angular!</h1> <h1>I'm Not Anti-Angular!</h1>
<i>Here's proof from 2014...</i> <i>Here's proof from 2014...</i>
<img src="/images/ng-conf.png" class="expandable" alt="Inside the inaugural Angular conference ngConf" <img src="/images/ng-conf.png" class="expandable" alt="Inside the inaugural Angular conference ngConf"
title="Inside the inaugural Angular conference ngConf" /> title="Inside the inaugural Angular conference ngConf" />

8
slides/data-binding.html Normal file
View File

@ -0,0 +1,8 @@
<title>Data-Binding Example 1</title>
<h1>Data-Binding Example</h1>
<ul>
<li repeat="list" class="appear">{{item.idx}} &mdash; {{item.value}}</li>
</ul>
<script>
this.list = [{idx: 0, value:"one"}, {idx: 1, value:"two"}, {idx: 2, value:"three"}];
</script>