Created
December 13, 2015 07:45
-
-
Save chinchang/7563658c9281e81c5502 to your computer and use it in GitHub Desktop.
Angular like watch and directive implementation concept using Object.observe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
function getObjectFromExpression(expr) { | |
var splits = expr.split('.'), | |
obj, propertyName; | |
if (splits.length === 1) { | |
obj = window; | |
propertyName = splits[0]; | |
} else { | |
obj = splits.slice(0, splits.length - 1).reduce(function (obj, key) { | |
return obj[key]; | |
}, window); | |
propertyName = splits[splits.length - 1]; | |
} | |
return { | |
obj: obj, | |
propertyName: propertyName | |
}; | |
}; | |
function camelCaseToHyphen (str) { | |
str = str.replace(/([A-Z])/g, '-$1'); | |
return str.toLowerCase(); | |
} | |
$ = {}; | |
$.directives = {}; | |
$.observers = {}; | |
$.compile = function (node) { | |
var i, j, k, | |
attributes = node.attributes; | |
for (var k = 0; k < attributes.length; k++) { | |
for (var name in this.directives) { | |
if (attributes[k].nodeName === this.directives[name].attrName) { | |
this.directives[name].init(node); | |
} | |
} | |
} | |
for (i = 0; i < node.children.length; i++) { | |
this.compile(node.children[i]); | |
} | |
}; | |
$.watch = function (expr, callback) { | |
var propertyName, exprStuff; | |
try { | |
exprStuff = getObjectFromExpression(expr); | |
} catch (e) { | |
exprStuff = { obj: window, propertyName: '' }; | |
} | |
// Add an observer on the obj | |
Object.observe(exprStuff.obj, function (changes) { | |
changes.forEach(function(change, i){ | |
if (change.name === exprStuff.propertyName) { | |
callback(change.object[change.name]); | |
} | |
}); | |
}, ['add', 'delete,', 'update']); | |
// Also fire the watch callback once | |
callback(exprStuff.obj[exprStuff.propertyName]); | |
} | |
$.registerDirective = function (name, definition) { | |
definition.attrName = camelCaseToHyphen(name); | |
this.directives[name] = definition; | |
}; | |
$.boot = function (node) { | |
node = node || document.body; | |
this.compile(node) | |
}; | |
// Sample ngShow Directive | |
$.registerDirective('ngShow', { | |
init: function (node) { | |
// TODO: Use a class to hide element instead of changing | |
// `display` style. | |
var originalDisplay = node.style.display; | |
$.watch(node.getAttribute('ng-show'), function (value) { | |
if (value) { | |
node.style.display = originalDisplay; | |
} else { | |
node.style.display = 'none'; | |
} | |
}); | |
} | |
}); | |
window.$ = $; | |
}); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
</head> | |
<body> | |
<div ng-show="obj.show"> | |
hello der | |
</div> | |
<script src="angular-with-o-o.js"></script> | |
<script> | |
var obj = { show: false }; | |
$.boot(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment