Skip to content

Instantly share code, notes, and snippets.

@WickyNilliams
Last active December 6, 2020 15:30
Show Gist options
  • Save WickyNilliams/9227916 to your computer and use it in GitHub Desktop.
Save WickyNilliams/9227916 to your computer and use it in GitHub Desktop.
Super simple one-way data-binding
/**
* follows a path on the given data to retrieve a value
*
* @example
* var data = { foo : { bar : "abc" } };
* followPath(data, "foo.bar"); // "abc"
*
* @param {Object} data the object to get a value from
* @param {String} path a path to a value on the data object
* @return the value of following the path on the data object
*/
function followPath(data, path) {
return path.split(".").reduce(function(prev, curr) {
return prev && prev[curr];
}, data);
}
/**
* sets value of an element based on it's data-value attribute
*
* @param {Object} data the data source
* @param {Element} element the element
*/
function bindSingleElement(data, element) {
var path = element.getAttribute("data-value");
element.innerText = followPath(data, path);
}
/**
* Binds data object to an element. Allows arbitrary nesting of fields
*
* @example
* <div class="user">
* <p data-value="name"></p>
* </div>
*
* var element = document.querySelector(".user");
* bind({ name : "Nick" }, element);
*
* @param {Object} data the data to bind to an element
* @param {Element} element the element to bind data to
*/
function bind(data, element) {
var holders = element.querySelectorAll("[data-value]");
[].forEach.call(holders, bindSingleElement.bind(null, data));
}
var user = {
"name" : "Nick",
"favourites" : {
"movie" : "foo",
"music" : "bar"
}
}
bind(user, document.querySelector(".user"));
<div class="user">
<h3 data-value="name"></h3>
<p>Fave Movie: <span data-value="favourites.movie"></span></p>
<p>Fave Music: <span data-value="favourites.music"></span></p>
</div>
@erperejildo
Copy link

erperejildo commented Jun 12, 2018

@WickyNilliams Thanks for this, works perfectly.

Just one thing. What about if we've got something like this:

var user = {
  "name" : "Nick",
  "favourites" : {
    "movie" : "foo",
    "music" : [{
        "title": "title 1",
        "band": "band 1"
     },{
        "title": "title 2",
        "band": "band 2"
     }]
  }
}

We could have from 0 to X elements inside music

Edit: I think for that specific scenario this would be one option https://codepen.io/erperejildo/pen/zazpVz?editors=1010

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment