angular-from-scratch

by Antoine

HTML

<body class="container text-center">
    <h1 class="page-header" ng-bind="labs.titre">Vide</h1>
    <input type="text" ng-model="labs.titre"/>
</body>

JavaScript

function Scope() {
    this.$$watchers = [];
}

Scope.prototype.$watch = function (watcherFn, listenerFn) {
    var watcher = {
        watcherFn: watcherFn,
        listenerFn: listenerFn,
        last: undefined
    };
    this.$$watchers.push(watcher);
}

Scope.prototype.$digest = function () {
    var dirty;
    do {
        dirty = false;
        _.each(this.$$watchers, function (watcher) {
            var newValue = watcher.watcherFn(this);
            if (watcher.last !== newValue) {
                watcher.listenerFn(newValue, watcher.last, this);
                watcher.last = newValue;
                dirty = true;
            }
        }.bind(this));
    } while (dirty);
}

Scope.prototype.$apply = function (exprFn) {
    try {
        exprFn();
    } finally {
        this.$digest();
    }
}
var $$directives = {};

var $directive = function (name, directiveFn) {
    if (directiveFn) {
        $$directives[name] = directiveFn;
    }
    return $$directives[name];
}

var $compile = function(element, scope) {
    _.each(element.children, function (child) {
       $compile(child, scope);
    });
    _.each(element.attributes, function(attribute) {
        var directiveFn = $directive(attribute.name);
        if (directiveFn) {
            directiveFn(scope, element, element.attributes);
        }
    });
}
$directive('ng-bind', function (scope, element, attributes) {
    scope.$watch(function(scope) {
        return eval('scope.' + attributes['ng-bind'].value);
    }, function(newValue) {
        element.innerHTML = newValue;
    });
});

$directive('ng-model', function(scope, element, attributes) {
    scope.$watch(function() {
        return eval('scope.' + attributes['ng-model'].value);
    }, function(newValue) {
        element.value = newValue;
    });
    element.addEventListener('keyup', function() {
        scope.$apply(function() {
            eval('scope.' + attributes['ng-model'].value + ' = \"' + element.value + '\"');
        });
   ...