Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to KnockoutJS

Avatar for romanych romanych
March 27, 2012
71

Introduction to KnockoutJS

Материалы с тренинга о KnockoutJS - Введение

Avatar for romanych

romanych

March 27, 2012
Tweet

Transcript

  1. Реальность в IT Никто не знает что надо делать, пока

    это не сделано  Программист  Менджмент  Бизнес
  2. r

  3. r

  4. <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); } Лучшая архитектура – её отсутствие
  5. <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); } Лучшая архитектура – её отсутствие?
  6. <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); } Взгляд на код со стороны
  7. <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 нам поможет?
  8. 10

  9. MVVM Model View View Model A ViewModel is basically a

    value converter on steroids. Josh Smith
  10. <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
  11. <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 в действии
  12. MVVM ViewModel • Color • Radius • SetRandomColor • Resize

    MVC Model • Color • Radius Controller • ColorChanged • RadiusChanged • SetRandomColor MVVM vs MVC
  13. - Не широко известый - Заставляет больше думать, где какой

    код писать + Скорость разработки + Много reusable кода + Плюсы и минусы MVVM
  14. С чего начинается приложение 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
  15. 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
  16. Пробуем 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
  17. Binding • Связывает ViewModel и View • Автоматическое обновление UI

    • Может быть двусторонним или односторонним • Позволяет усложнять View не усложняя ViewModel 23
  18. Стандартные 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
  19. Двустороннее и одностороннее связывание <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
  20. Пример 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
  21. Препарируем 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
  22. Препарируем ko.computed Evaluate computed // first time evaluation b(true) =>

    b changed to true a(false) => a changed to false; Evaluate computed 28
  23. Препарируем 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