Last active
May 27, 2023 10:58
-
-
Save smelukov/abd9b366164461ec5a9f to your computer and use it in GitHub Desktop.
Very simple MVVM (dynamic data binding) on JS
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"> | |
<title>Title</title> | |
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>MVVM</h1> | |
<form role="form"> | |
<div class="checkbox"> | |
<label> | |
<input type="checkbox" checked id="bindingEnabled"> Динамическое связывание | |
</label> | |
</div> | |
<div class="form-group"> | |
<label for="firstName">Имя</label> | |
<input type="text" class="form-control" id="firstName" data-bind="firstName"> | |
</div> | |
<div class="form-group"> | |
<label for="lastName">Фамилия</label> | |
<input type="text" class="form-control" id="lastName" data-bind="lastName"> | |
</div> | |
<div class="form-group"> | |
<label for="old">Возраст</label> | |
<input type="text" class="form-control" id="old" data-bind="old"> | |
</div> | |
<div class="form-group"> | |
<label for="town">Город</label> | |
<input type="text" class="form-control" id="town" data-bind="town"> | |
</div> | |
</form> | |
<hr> | |
<div class="jumbotron"> | |
<h1>Привет!</h1> | |
<p>Меня зовут <span data-bind="firstName"></span> <span data-bind="lastName"></span>.</p> | |
<p>Мне <span data-bind="old"></span> лет и я живу в городе <span data-bind="town"></span>.</p> | |
</div> | |
</div> | |
<script src="script.js"></script> | |
</body> | |
</html> |
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
var bindMap = {}, | |
scope = {}, | |
bindedEls = document.querySelectorAll('*[data-bind]'); | |
for (var i = 0; i < bindedEls.length; i++) { | |
var el = bindedEls[i], | |
bindTo = el.dataset.bind; | |
if (!bindMap[bindTo]) { | |
bindMap[bindTo] = []; | |
} | |
bindMap[bindTo].push(el); | |
} | |
function bindValue(bindingName, value) { | |
scope[bindingName] = value; | |
} | |
function syncBindings() { | |
for (var bindTo in scope) { | |
var value = scope[bindTo]; | |
bindMap[bindTo].forEach(function(el) { | |
if (el.tagName === 'INPUT') { | |
el.value = value; | |
} else { | |
el.innerText = value; | |
} | |
}); | |
delete scope[bindTo]; | |
} | |
} | |
document.addEventListener('keyup', function(e) { | |
var target = e.target, | |
bindTo = target.dataset.bind; | |
if (bindTo && bindMap[bindTo]) { | |
bindValue(bindTo, target.value); | |
if (bindingEnabled.checked) { | |
syncBindings(); | |
} | |
} | |
}, true); | |
bindingEnabled.addEventListener('change', function() { | |
if (bindingEnabled.checked) { | |
syncBindings(); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment