vanillajs-deck/js/dataBinding.js
2019-11-26 09:15:12 -08:00

50 lines
1.7 KiB
JavaScript

// @ts-check
export class DataBinding {
/**
* Simple evaluation
* @param {string} js The JavaScript to evaluate
*/
execute(js) {
return eval(js);
}
/**
* Evaluates JavaScript with a constrained context (scope)
* @param {string} src The JavaScript to evaluate
* @param {object} context The context (data) to evaluate with
* @returns {object} The result of the evaluation
*/
executeInContext(src, context) {
return this.execute.call(context, src);
}
/**
* Searches for "repeat" attribute to data-bind lists
* @param {HTMLElement} elem The parent element to search
* @param {object} context The context to use for binding
*/
bindLists(elem, context) {
const listBinding = elem.querySelectorAll("[repeat]");
listBinding.forEach(elem => {
const parent = elem.parentElement;
const expression = elem.getAttribute("repeat");
elem.removeAttribute("repeat");
const template = elem.outerHTML;
parent.removeChild(elem);
context[expression].forEach(item => {
let newTemplate = `${template}`;
const matches = newTemplate.match(/\{\{([^\}]*?)\}\}/g);
if (matches) {
matches.forEach(match => {
match = match.replace("{{", "").replace("}}", "");
const value = this.executeInContext(`this.${match}`, {item});
newTemplate = newTemplate.replace(`{{${match}}}`, value);
});
parent.innerHTML += newTemplate;
}
});
});
}
}