Skip to content

Instantly share code, notes, and snippets.

@yangfch3
Last active August 23, 2018 01:22
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 yangfch3/74c2acec98ffd24b47e66a86ff86ae79 to your computer and use it in GitHub Desktop.
Save yangfch3/74c2acec98ffd24b47e66a86ff86ae79 to your computer and use it in GitHub Desktop.
Angular核心实现讲解代码
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Angular Core Implementation</title>
</head>
<body ng-app="myApp">
<div>
<form>
<input type="text" ng-bind="count" />
<button type="button" ng-click="increment">increment</button>
</form>
<div ng-bind="count"></div>
</div>
<script>
class Watcher {
constructor(name, listener, $scope) {
this.name = name;
this.$scope = $scope;
this.last = '';
this.listener = listener || function () {};
}
getNewVal() {
return this.$scope[this.name]
}
}
class Scope {
constructor() {
this.$$watchers = [];
}
$watch(name, listener) {
this.$$watchers.push(new Watcher(name, listener, this));
}
$digest() {
const bindList = document.querySelectorAll('[ng-bind]');
let dirty = true;
while (dirty) {
dirty = false;
for (let i = 0, len = this.$$watchers.length; i < len; i++) {
let newVal = this.$$watchers[i].getNewVal(),
oldVal = this.$$watchers[i].last;
if (newVal !== oldVal &&
!isNaN(newVal) &&
!isNaN(oldVal)) {
this.$$watchers[i].listener(oldVal, newVal);
this.$$watchers[i].last = newVal;
for (let j = 0, len = bindList.length; j < len; j++) {
let modelName = bindList[j].getAttribute('ng-bind');
if (modelName === this.$$watchers[i].name) {
if (bindList[j].tagName === 'INPUT') {
bindList[j].value = this[modelName];
} else {
bindList[j].innerHTML = this[modelName];
}
}
}
}
}
}
}
}
const angular = {
module(root) {
let context = document.querySelector(`[ng-app=${root}]`);
context && (this.context = context);
return context ? this : null;
},
controller(ctrlName, constructor) {
this.$scope = $scope = new Scope();
constructor($scope);
let bindList = this.context.querySelectorAll('[ng-click]');
for (let i = 0, len = bindList.length; i < len; i++) {
bindList[i].onclick = function () {
$scope[bindList[i].getAttribute('ng-click')]();
$scope.$digest();
}
}
let inputList = this.context.querySelectorAll('input[ng-bind]');
for (let i = 0, len = inputList.length; i < len; i++) {
inputList[i].addEventListener('input', function () {
$scope[inputList[i].getAttribute('ng-bind')] = inputList[i].value;
$scope.$digest();
});
}
$scope.$digest();
}
}
</script>
<script>
const myConsole = console;
angular.module('myApp').controller('myAppCtrl', function ($scope) {
$scope.count = 0;
$scope.increment = function () {
this.count++;
};
$scope.$watch('count', function (oldVal, newVal) {
myConsole.log(`${oldVal} => ${newVal}`);
})
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment