Monday, 3 November 2014

Angular from scratch

Basic change detection scope and directives implemented in one page of code, basically it’s Angular without Angular!

image

Video: https://www.youtube.com/watch?v=Mk2WwSxK218

Demo: http://stevenhollidge.com/blog-source-code/angular-from-scratch

Code:

<html>
<head>
<title>Angular From Scratch</title>
<style>
body {
height: 100%;
margin: 0;
background-image: url('slides/img/whitepage.jpg');
display: flex;
flex-direction: column;
justify-content: center;
}
h1, h2 {
font-family: 'Cherry Cream Soda', cursive;
font-size: 4em;
text-align: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.5);
color: white;
padding: .2em;
margin: 0;
}
input {
font-size: .5em;
margin: .5em;
border-radius: .2em;
border: none;
}
</style>
</head>
<body>
<h1 ng-bind="hello">hello</h1>
<h2><input type="text" ng-model="hello"></h2>
<script>
'use strict';
// scope
var Scope = function() {
this.$$watchers = [];
this.$watch = function(watcherFn, listenerFn) {
this.$$watchers.push({
watcherFn: watcherFn,
listenerFn: listenerFn
});
};
this.$digest = function() {
this.$$watchers.forEach(function(watcher) {
var newValue = watcher.watcherFn();
var oldValue = watcher.last;
if(newValue !== oldValue) {
watcher.listenerFn(newValue, oldValue);
watcher.last = newValue;
}
});
};
this.$apply = function(exprFn) {
try {
exprFn();
} finally {
this.$digest();
}
};
};
var $scope = new Scope();
// compiler
var $$directives = {
'ng-bind': function($scope, $element, $attributes) {
$scope.$watch(function() {
return $scope[$attributes['ng-bind'].value];
}, function(newValue) {
$element.innerHTML = newValue;
});
},
'ng-model': function($scope, $element, $attributes) {
$scope.$watch(function() {
return $scope[$attributes['ng-model'].value];
}, function(newValue) {
$element.value = newValue;
});
$element.addEventListener('keyup', function() {
$scope.$apply(function() {
$scope[$attributes['ng-model'].value] = $element.value;
});
});
}
};
var $compile = function(element, $scope) {
Array.prototype.forEach.call(element.children, function(child) {
$compile(child, $scope);
});
Array.prototype.forEach.call(element.attributes, function(attribute) {
var directive = $$directives[attribute.name];
if(directive) {
directive($scope, element, element.attributes);
}
});
};
$compile(document.body, $scope);
// tests & logs
$scope.hello = 'Hello ng-Europe';
$scope.$watch(function() {
return $scope.hello;
}, function(newValue, oldValue) {
console.log('hello changed from', oldValue, 'to', newValue);
});
</script>
</body>
</html>

No comments:

Post a Comment