Another look at knockout

advertisement
Another look at Knockout JS
By Peter Messenger
Senior Developer – Triple Point Technology
http://www.petermessenger.com
What is Knockout JS?
• Knockout is a JavaScript library that helps you
to create rich, responsive display and editor
user interfaces with a clean underlying data
model. Any time you have sections of UI that
update dynamically (e.g., changing depending
on the user’s actions or when an external data
source changes), KO can help you implement
it more simply and maintainably.
Knockout JS - Site
• Developed originally by Steve Sanderson
– http://blog.stevensanderson.com/about/
– Microsoft employee, working in England
• Open Source Framework
• Available on Github, Nuget
• In active development, currently version 3.0
• More Information on
– http://knockoutjs.com/
Simple Example
Javascript:
var myViewModel = {firstName: ‘Peter', lastName: ‘Messenger’};
Html :
The name is <span data-bind="text: firstName"></span>
Javascript :
ko.applyBindings(myViewModel);
Result:
The name is <span>Peter</span>
Why is this important?
• Based on the MVVM design pattern
– MVVM stands for Model, View, ViewModel
• A model: your application’s stored data.
• A view model: a pure-code representation of the data
and operations on a UI
• A view: a visible, interactive UI representing the state of
the view model.
– Keeps the logic and presentation layer separated
– Much easier to maintain, less prone to error
Extending Example - Observables
Javascript:
var myViewModel = {firstName: ko.observable(‘Peter‘), lastName:
ko.observable(‘Messenger’)};
Result:
Exactly the same as before, but….
If personName changes for any reason, the display will automatically
change.
Extending
myViewModel.firstName.subscribe(function(newValue) {
alert("The person's new name is " + newValue);
});
Extending Example - Computed
Javascript:
function Person(firstName,lastName) {
this.firstName = ko.observable(firstName);
this.lastName = ko.observable(lastName);
this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
}
var myViewModel = Person(“Peter”,”Messenger”);
Result:
Exactly the same as before, but….
Can bind to fullName, and this will change, if first name or last name
change
Extending Examples - Arrays
Javascript:
var myViewModel = {people : ko.observableArray()};
myViewModel.people.push(Person(“Peter”,”Messenger”));
myViewModel.people.push(Person(“John”,”Smith”));
myViewModel.people.push(Person(“Sarah”,”Parker”));
Html:
<table>
<thead>
<tr><th>First name</th><th>Last name</th></tr>
</thead>
<tbody data-bind="foreach: people">
<tr>
<td data-bind="text: firstName"></td>
<td data-bind="text: lastName"></td>
</tr>
</tbody>
</table>
Extending Example - Actions
Javascript:
function PeopleModel() {
var self = this;
self.people = ko.observableArray([
Person(“Peter”,”Messenger”),
Person(“John”,”Smith”),
Person(“Sarah”,”Parker”)
]);
self.addPerson = function() {
self.people.push(Person(“New Guy”,"New at " + new Date()));
};
self.removePerson = function() {
self.people.remove(this);
}
}
Extending Example – Actions (cont)
Html:
<h4>People</h4>
<ul data-bind="foreach: people">
<li>
Name at position <span data-bind="text: $index"> </span>:
<span data-bind="text: name"> </span>
<a href="#" data-bind="click: $parent.removePerson">Remove</a>
</li>
</ul>
<button data-bind="click: addPerson">Add</button>
Example Here
•
$index is used to mark the position in the array
•
$parent allows it to jump back a level, $parent can be nested $parent[2] is parent of parent
•
http://knockoutjs.com/documentation/foreach-binding.html
Existing Bindings
Text and appearance
Visible, text, html, css, style, attr
Control flow
Foreach, if, ifnot, with
Forms
Click, Event, Submit, Enable, Disable, HasFocus,
Checked, Options, SelectedOptions
Building your own bindings
Javascript
ko.bindingHandlers.yourBindingName = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called when the binding is first applied to an element
// Set up any initial state, event handlers, etc. here
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called once when the binding is first applied to an element,
// and again whenever the associated observable changes value.
// Update the DOM element based on the supplied values here.
}
};
Html
<div data-bind="yourBindingName: someValue"> </div>
Wiring up to services (Jquery)
Get
$.getJSON("/some/url", function(data) {
})
Post
var data = /* Your data in JSON format - see below */;
$.post("/some/url", data, function(returnedData) {
// This callback is executed if the post was successful
})
Converting
var jsonData = ko.toJSON(viewModel);
More documentation
• There is extensive documentation on the main
site
–
–
–
–
Interactive tutorials
Live examples
Forum
Easy to integrate with JSON based services
As the popularity of knockout has increased, many o the
javascript UI frameworks have added knockout
extensions.
Added in Version 3.0
• Clearer error reporting
• Custom binding, now extensible
• Bindings now independent and only refresh
when needed
• Computed variables now only notify when
they are changed
• Performance and bug fixes
Integration – Other Frameworks
• Kendo UI (Telerik)
– http://rniemeyer.github.io/knockout-kendo/
• JQuery UI
– http://gvas.github.io/knockout-jqueryui/index.html
• jqWidgets
– http://www.jqwidgets.com/
• Wijmo (Component One)
– http://wijmo.com/demo/explore/?widget=Knockout&
sample=Overview
jQuery UI Examples
http://gvas.github.io/knockout-jqueryui/index.html
•
•
•
•
•
Accordion
AutoComplete
Button
Dialog
Menu
Why do I like it?
• Once you get the hang of it, it is quite easy
and nice to use and debuggable
• Can develop “single page” websites that are
fast and responsive
• Very lean, much less “post back bloat” than
MVC
• Can have html/javascript separate, easier to
style with css
A full website based on Knockout JS
https://www.petermessenger.com/Exercises.aspx
Important Links?
• Presentation slides on my website and blog
– http://www.petermessenger.com
– Main Site:
• http://knockoutjs.com/
– Good Reference Site:
• http://www.knockmeout.net/
Download