基础知识
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>
<input type="text" ng-bind="name" />
<button type="button" ng-click="increment">increment</button>
<div ng-bind="name"></div>
</div>
<script>
class Watcher {
constructor(name, last, exp, listener) {
this.name = name; // 数据变量名
this.last = last; // 数据变量旧值
this.newVal = exp; // 返回数据变量新值的函数
this.listener = listener || function () {}; // 监听回调函数,变量“脏”时触发
this.listener(this.last, this.newVal());
}
}
class Scope {
constructor() {
// 观察者数组
this.watchers = [];
}
// 添加数据观察者
watch(name, exp, listener) {
this.watchers.push(new Watcher(name, "", exp, listener));
}
// 对监视器的新旧值进行对比
// 当新旧值不同时,调用listener函数进行相应操作
// 并将旧值更新为新值。它将不断重复这一过程,直到所有数据变量的新旧值相等:
digest() {
let dirty = true;
while (dirty) {
dirty = false;
this.watchers.forEach(watcher => {
let newVal = watcher.newVal();
var oldVal = watcher.last;
if (newVal !== oldVal) {
dirty = true;
watcher.listener(oldVal, newVal);
watcher.last = newVal;
}
});
}
}
}
class App extends Scope {
name = "Ajanuw";
constructor() {
super();
}
increment() {
this.name += "+";
}
}
const app = new App();
run(app);
function run(app) {
document // 绑定依赖观察者
.querySelectorAll("[ng-bind]")
.forEach(it => {
const nodeName = it.nodeName.toLowerCase();
const bindKey = it.getAttribute("ng-bind");
if (bindKey in app) {
app.watch(
bindKey,
() => app[bindKey],
(oldVal, newVal) => {
if (nodeName === "input") {
it.value = newVal;
} else {
it.textContent = newVal;
}
}
);
}
});
// 绑定事件
document.querySelectorAll("[ng-click]").forEach(it => {
const bindKey = it.getAttribute("ng-click");
it.addEventListener("click", e => {
if (app[bindKey] && typeof app[bindKey] === "function") {
app[bindKey]();
app.digest();
}
});
});
// 双向绑定
document.querySelectorAll("input[ng-bind]").forEach(it => {
const bindKey = it.getAttribute("ng-bind");
it.addEventListener("input", e => {
app[bindKey] = it.value;
app.digest();
});
});
}
</script>
</body>
</html>