Skip to content

Instantly share code, notes, and snippets.

@arobson
Created September 2, 2011 05:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arobson/1187993 to your computer and use it in GitHub Desktop.
Save arobson/1187993 to your computer and use it in GitHub Desktop.
An ugly POC for decoupled 'binding' in Javascript
var DomWriter = function (target, namespace) {
var instance = this;
var template = namespace;
var coalesce = function( value, defaultValue ) {
return typeof(value) != 'undefined' ?
value : defaultValue;
};
this.isObject = function( value ) {
return typeof(value) === 'object';
};
this.addSubscription = function( path, element ) {
postal.subscribe( "binding", path, function( msg ) {
instance.write( path, msg );
});
if( _(instance[path]).isUndefined() ) {
instance[path] = element;
}
};
this.crawl = function( namespace, element, callback ) {
_(element)
.chain()
.keys()
.each( function( key ) {
var child = element[key];
var fqn = namespace === "" ?
key : namespace + "." + key;
callback( namespace, key, child );
if( !_.isNull( child ) && instance.isObject( child ) ) {
instance.crawl( fqn, child, callback );
}
});
};
this.domCrawl = function( namespace, element, callback ) {
var id = coalesce( element["id"], "" );
var fqn = namespace == "" ?
id : ( id === "" ? namespace : namespace + "." + id );
callback( fqn, id, element );
if( element.children !== undefined &&
element.children.length > 0 ) {
_(element.children)
.chain()
.each( function( child ) {
instance.domCrawl(
fqn,
child,
callback );
});
}
};
this.domCrawl( "", target[0], function( namespace, key, child ) {
var prefix = template + ".";
var member = namespace === template ?
namespace : namespace.replace( prefix, "", "gi");
instance.addSubscription( member, child );
});
this.write = function( path, value ) {
element = this[path];
this[$(element)[0].tagName.toLowerCase()]
( path, element, value );
};
this.div = function( fqn, element, value ) {
if( instance.isObject( value ) ) {
instance.crawl( "", value, function( namespace, key, child ) {
instance.write(
namespace === "" ? key : namespace + "." + key,
child );
});
}
else {
$(element).text( value );
}
};
this.span = function( fqn, element, value ) {
$(element).text( value );
};
this.input = function( fqn, element, value ) {
$(element).val( value );
};
this.ul = function( fqn, element, value ) {
var children = $(element).children("li");
if( children.length < value.length ) {
$(element).empty();
var li = children[0];
var indx = 0;
_(value)
.each( function( child ) {
var newLi = $(li)
.clone()
.attr( "id", indx )
.appendTo( element );
instance[ fqn + "." + indx ] = newLi[0];
instance.domCrawl(
fqn,
newLi[0],
function( namespace, key, child ) {
var prefix = template + ".";
var member = namespace === template ?
namespace : namespace.replace( prefix, "", "gi");
instance.addSubscription( member, child );
}
);
indx++;
});
}
};
this.li = function( fqn, element, value ) {
$(element).text( value );
};
};
<html>
<head>
<script src="/scripts/binder.js" type="text/javascript"></script>
<script src="/scripts/underscore-min.js" type="text/javascript"></script>
<script src="/scripts/jquery-1.6.2.min.js"
type="text/javascript"></script>
<script src="/scripts/postal.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
var alex =
{
"firstname" : "Alex ",
"lastname" : "Robson",
"hobbies" :
[
"CODE ALL THE THINGS",
"Watching my stories",
"Reading"
],
"relatives":
[
{"firstname" : "Ian", "lastname" : "Robson" },
{"firstname" : "Sean", "lastname" : "Robson" },
]
};
$(function() {
var writer = new DomWriter($("#person"), "person");
writer.write( "person", alex );
postal.publish( "binding", "hobbies.0", "Taking big dumps." );
});
</script>
</head>
<body>
<div id="person">
<!--<span id="firstname"></span>-->
<!--<span id="lastname"></span>-->
<input type="text" id="firstname" />
<input type="text" id="lastname" />
<ul id="hobbies">
<li></li>
</ul>
<ul id="relatives">
<li>
<span id="firstname"></span>
<span id="lastname"></span>
</li>
</ul>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment