Skip to content

Instantly share code, notes, and snippets.

@felixlaumon
Created July 15, 2013 15:28
Show Gist options
  • Save felixlaumon/6000885 to your computer and use it in GitHub Desktop.
Save felixlaumon/6000885 to your computer and use it in GitHub Desktop.
<!doctype>
<html>
<head>
<script src="/app/components/rivets/dist/rivets.js"></script>
<script src="/app/components/ChangeSummary/change_summary.js"></script>
<script src="/app/components/lodash/lodash.js"></script>
</head>
<body>
<ul>
<li data-rv-prerendered data-mapper='root.nameMapper'>
<span>John</span> - <span>Doe</span>
</li>
<li data-rv-prerendered data-mapper='root.nameMapper'>
<span>Mary</span> - <span>Doe</span>
</li>
<li data-rv-prerendered data-mapper='root.nameMapper'>
<span>Peter</span> - <span>Doe</span>
</li>
<li data-rv-each-item="root.items">
<span data-rv-text="item.firstName"></span> -
<span data-rv-text="item.lastName"></span>
</li>
</ul>
<script>
// Custom binders code
var _preRenders = [];
rivets.binders['prerendered'] = function (el, value) {
// TODO: find a way to close out these observers
var prefix = this.view.config.prefix;
var mapper = this.view.config.adapter.read(this.model, el.dataset.mapper);
var data = mapper(el);
_preRenders.push({
el: el,
data: data,
parentNode: el.parentNode
});
// Remove dataset
_.each(el.dataset, function (val, key) {
if (key.indexOf(prefix) >= 0) {
delete el.dataset[key];
}
});
};
var origRoutine = rivets.binders['each-*'].routine;
rivets.binders['each-*'].routine = function (el, collection) {
eachBinding = this;
var _this = this;
var options = this.options;
var modelName = this.args[0];
if (!_this.view.els || !_this.view.els.length) {
return;
}
var matchedPrerenders = _preRenders.filter(function (preRender) {
return preRender.parentNode === _this.view.els[0];
});
_.each(matchedPrerenders, function (preRender, i) {
var model = {};
// TODO: copy all dataset properties recursively for all children
_.extend(preRender.el.dataset, el.dataset);
_.each(preRender.el.children, function (child, i) {
_.extend(child.dataset, el.children[i].dataset);
});
// Copy data to the binded object
_.extend(collection[i], preRender.data);
// Gather the model
model[modelName] = collection[i];
model = _.defaults(model, _this.view.models);
var view = new rivets._.View(preRender.el, model, options);
view.bind();
_this.iterated.push(view);
});
// Clear preRender
_preRenders = _.difference(_preRenders, matchedPrerenders);
// Run the originally function
origRoutine.apply(this, arguments);
}
function get (obj, keypath) {
var val = obj;
keypath.split('.').forEach(function (path) {
val = val[path];
});
return val;
}
function set (obj, keypath, val) {
var paths = keypath.split('.');
var lastPath = _.last(paths);
var curObj = obj;
var i;
var length;
var path;
for (i = 0, length = paths.length - 1; i < length; i++) {
// Stop iterating at the second last path
path = paths[i];
curObj = curObj[path];
}
curObj[lastPath] = val;
}
var observers = [];
rivets.configure({
adapter: {
subscribe: function(obj, keypath, callback) {
console.log('subscribe', obj, keypath);
obj._observerId = observers.length;
var actualObj = get(obj, keypath);
var observer;
if (Array.isArray(actualObj)) {
// console.log('ArrayObserver');
observer = new ArrayObserver(actualObj, callback);
} else {
// console.log('PathObserver');
observer = new PathObserver(obj, keypath, callback);
}
observers.push(observer);
},
unsubscribe: function(obj, keypath, callback) {
console.log('unsubscribe', obj, keypath);
observers[obj._observerId].close();
},
read: function(obj, keypath) {
console.log('read', obj, keypath, get(obj, keypath));
return get(obj, keypath);
},
publish: function(obj, keypath, value) {
console.log('publish', obj, keypath, value);
set(obj, keypath, value);
}
},
prefix: 'rv'
});
// Demo data
function nameMapper (el) {
return {
firstName: el.children[0].innerHTML,
lastName: el.children[1].innerHTML,
};
}
var items = [
{ },
{ },
{ }
];
var root = { items: items, nameMapper: nameMapper };
// Mutation Obsrever code
var target = document.querySelector('ul');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation);
});
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);
// Bind view
window.view = rivets.bind(document.querySelector('ul'), { root: root });
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment