Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Introduction to KnockoutJS
Search
romanych
March 27, 2012
0
71
Introduction to KnockoutJS
Материалы с тренинга о KnockoutJS - Введение
romanych
March 27, 2012
Tweet
Share
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.6k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Embracing the Ebb and Flow
colly
87
4.8k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
The Cost Of JavaScript in 2023
addyosmani
53
8.9k
Thoughts on Productivity
jonyablonski
70
4.8k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.9k
Java REST API Framework Comparison - PWX 2021
mraible
33
8.8k
Music & Morning Musume
bryan
46
6.8k
Why Our Code Smells
bkeepers
PRO
339
57k
Building a Modern Day E-commerce SEO Strategy
aleyda
43
7.6k
Transcript
Базовый тренинг по KnockoutJS Roman Gomolko
[email protected]
@romanych
Реальность в IT Никто не знает что надо делать, пока
это не сделано Программист Менджмент Бизнес
r
r
<svg> <circle id="circle" cx="110" cy="110" r="50" stroke="red" fill="transparent“ /> </svg>
<div> Radius: <input type="range" min="10" max="100" step="1" id="radius" value="50" /> Color: <input type="text" id="color" value="red" /> var circle = document.getElementById('circle'), radiusField = document.getElementById('radius'), colorField = document.getElementById('color'); radiusField.onchange = function () { circle.setAttribute('r', radiusField.value); } colorField.onchange = function () { circle.setAttribute('stroke', colorField.value); } Лучшая архитектура – её отсутствие
<svg> <circle id="circle" cx="110" cy="110" r="50" stroke="red" fill="transparent“ /> <text
id="radiusLabel"></text> </svg> Radius: <input type="range" min="10" max="100" step="1" id="radius" value="50" /> Color: <input type="text" id="color" value="red" /> var circle = document.getElementById('circle'), radiusField = document.getElementById('radius'); colorField = document.getElementById('color'); circle.onclick = function () { var c = random_color(); circle.setAttribute('stroke', colorField.value); colorField.value = c; } circle.onresize = function () { radiusField.value = circle.getAttribute('r'); radiusLabel.innerText = radiusField.value + 'px'; } radiusField.onchange = function () { circle.setAttribute('r', radiusField.value); radiusLabel.innerText = radiusField.value + 'px'; } colorField.onchange = function () { circle.setAttribute('stroke', colorField.value); } Лучшая архитектура – её отсутствие?
<svg> <circle id="circle" cx="110" cy="110" r="50" stroke="red" fill="transparent“ /> <text
id="radiusLabel"></text> </svg> Radius: <input type="range" min="10" max="100" step="1" id="radius" value="50" /> Color: <input type="text" id="color" value="red" /> var circle = document.getElementById('circle'), radiusField = document.getElementById('radius'); colorField = document.getElementById('color'); circle.onclick = function () { var c = random_color(); circle.setAttribute('stroke', c); colorField.value = c; } circle.onresize = function (e, r) { radiusField.value = r; radiusLabel.innerText = radiusField.value + 'px'; } radiusField.onchange = function () { circle.setAttribute('r', radiusField.value); radiusLabel.innerText = radiusField.value + 'px'; } colorField.onchange = function () { circle.setAttribute('stroke', colorField.value); } Взгляд на код со стороны
<svg> <circle id="circle" cx="110" cy="110" r="50" stroke="red" fill="transparent“ /> <text
id="radiusLabel"></text> </svg> Radius: <input type="range" min="10" max="100" step="1" id="radius" value="50" /> Color: <input type="text" id="color" value="red" /> var circle = $('#circle'), radiusField = $('#radius'), colorField = $('#color'); circle.click(function () { var c = random_color(); circle.attr('stroke', c); colorField.val(c); }); circle.bind(‘resize ‘, function (e, r) { radiusField.val(r); radiusLabel.text(radiusField.value + 'px'); }); radiusField.bind(‘change, function () { circle.attr('r', radiusField.value); radiusLabel.text(radiusField.value + 'px'); }); colorField.bind(‘change‘, function () { circle.attr('stroke', colorField.val()); }); jQuery нам поможет?
None
10
MVVM Model View View Model A ViewModel is basically a
value converter on steroids. Josh Smith
<svg> <circle cx="110" cy="110" r="?" stroke="?" fill="transparent“ onclick="setRandomColor()"/> <text>?</text> </svg>
Radius: <input type="range" min="10" max="100" step="1" value="?" /> Color: <input type="text" value="?" /> var ui= { radius: 50, color: 'red', setRandomColor: function() { ui.color = get_random_color() } } Взгляд на задачу со стороны MVVM
Knockout 13
<svg> <circle cx="200" cy="200" fill="transparent" data-bind="attr: { stroke: color, r:
radius}, event: { click: randomizeColor, resize: resize }" /> <text data-bind="text: radius() + 'px'"></text> </svg> Radius: <input type="range" min="10" max="100" step="1" data-bind="value: radius" /> Color: <input type="text" data-bind="value: color" /> var viewModel = { radius: ko.observable(50), color: ko.observable('red'), randomizeColor: function () { this.color(random_color()); }, resize: function(e, r) { this.radius(r); } }; ko.applyBindings(viewModel); Knockout в действии
MVVM vs MVC vs MVP
MVVM ViewModel • Color • Radius • SetRandomColor • Resize
MVC Model • Color • Radius Controller • ColorChanged • RadiusChanged • SetRandomColor MVVM vs MVC
MVVM is realtime MVC
- Не широко известый - Заставляет больше думать, где какой
код писать + Скорость разработки + Много reusable кода + Плюсы и минусы MVVM
Из чего стоит KnockoutJS Инфраструктура • Observables • Utility functions
Представление • Bindings • Templating 19
С чего начинается приложение var viewModel = { firstName: ko.observable(),
lastName: ko.observable() }; ko.applyBindings(viewModel); <form> <input type=“text” data- bind=“value: firstName , valueUpdate: ‘afterkeydown’” /> <input type=“text” data- bind=“value: lastName” /> </form> <label data-bind=“text: firstName”></label> <label data-bind=“text: lastName”></label> 20
Observables ko.observable() ko.observableArray() ko.computed() он же ko.dependentObservable() var firstName =
ko.observable() firstName() => undefined firstName(‘Casper’); firstName() => Casper var firstName = ko.observable(), lastName=ko.observable(); var fullName = ko.computed(function() { return firstName() + ' ' + lastName(); }); firstName('Richard'); lastName('Gere') fullName() => 'Richard Gere'; Observables позволяют следить за изменением значений 21
Пробуем ko.computed var viewModel = { firstName: ko.observable(), lastName: ko.observable()
}; viewModel.fullName = ko.computed(function() { return this.firstName() + ' ' + this.lastName(); }, viewModel); ko.applyBindings(viewModel); <input type="text" data- bind="value: firstName, valueUpdate: 'afterkeydown'" /> <input type="text" data- bind="value: lastName, valueUpdate: 'afterkeydown'" /> <span data-bind="text: fullName"></span> 22
Binding • Связывает ViewModel и View • Автоматическое обновление UI
• Может быть двусторонним или односторонним • Позволяет усложнять View не усложняя ViewModel 23
Стандартные Bindings Content & Appearance • text • html •
visible • css • style • attr Forms & Data • value • checked • enable • disable • options • selectedOptions … Control flow • if • ifnot • foreach • with Templating • template 24
Двустороннее и одностороннее связывание <input type=“text” data-bind=“value: firstName, valueUpdate: ‘afterkeydown’”
/> <input type=“text” data-bind=“value: firstName(), valueUpdate: ‘afterkeydown’” /> <span data-bind=“text: firstName”></span> 25
Пример binding’а ko.bindingHandlers['value'] = { 'init': function (element, valueAccessor, allBindingsAccessor)
{ element.onchange = function () { var modelValue = valueAccessor(); var elementValue = element.value; if (ko.isWriteableObservable(modelValue)) modelValue(elementValue); }; }, 'update': function (element, valueAccessor) { var newValue = ko.utils.unwrapObservable(valueAccessor()); var elementValue = element.value; var valueHasChanged = (newValue != elementValue); if (valueHasChanged) element.value = newValue; } }; 26
Препарируем ko.computed observable.subscribe(handler, bindingContext, event) var a = ko.observable(true), b
= ko.observable(false); a.subscribe(function(newA) { console.log(‘a changed to ‘, newA); }); b.subscribe(function(newB) { console.log(‘b changed to ‘, newB); }); var cmp = ko.computed(function() { console.log(‘Evaluate computed’); return a() || b(); }); 27
Препарируем ko.computed Evaluate computed // first time evaluation b(true) =>
b changed to true a(false) => a changed to false; Evaluate computed 28
Препарируем bindings ko.applyBindings() => for each node with data-bind: var
isFirstTime = true; ko.computed(function () { var bindings = eval("{" + element['data-bind'] + "}"); for (var binding in bindings) { if (ko.bindingHandlers[binding]) { if (isFirstTime) { isFirstTime = false; ko.bindingHandlers[binding].init(element, bindings[binding], bindings); } ko.bindingHandlers[binding].update(element, bindings[binding], bindings); } } }); 29
Полезные функции • ko.utils.unwrapObservable() • ko.isObservable() • ko.isSubscribable() • ko.isWriteableObservable()
30
Пример с фильтрацией grid’а 31