2. Flavius-Radu Demian
Software developer, Avaelgo
I really like programming, web and mobile especially.
Please feel free to ask questions any time and don’t be shy because
Knowledge is power
flaviusdemian91@yahoo.com | flavius.demian@gmail.com | @slowarad
3. Expectations
Learn how the MVVM pattern works
Learn the basics of Knockout JS
Learn the advantages and limitations of Knockout JS => when to
use it and when not to
Understand that knockout want to be friends to everyone
4. Expectations
And the most important expectations is:
Make you curious => go home and try it and/or
convince your PM at work in order for him to let you use it
5. Agenda
The MVVM Pattern
Welcome to Knockout
Headline Features
Bindings
Templates
Mapping and unmapping
Navigation
Testing
Samples
Conclusions
6. Whats is MVVM
The Model-View-View Model (MVVM) pattern is a software architectural design
pattern.
This pattern emerged in 2005 to support the inherent data binding functionality
offered by XAML subsystems such as WPF and Silverlight.
Related patterns: MVC ( ex: asp .net mvc), MVP ( ex: windows forms) . MVVM (
ex: WPF, Silverlight) is based on MVC and it is a specialization of MVP.
More explanations at this link.
7. What is MVVM - Model
The Model encapsulates the domain model, business logic and may include data
access.
User
{
username,
firstname,
lastname,
email
}
8. What is MVVM - View
The view is the application’s User Interface (UI).
It defines the appearance of the UI and its visual elements and controls such as
text boxes and buttons.
The view may also implement view behavior such as animations and transitions.
9. What is MVVM - ViewModel
The view model is responsible for holding application state, handling
presentation logic and exposing application data and operations (commands) to
the view such (ex: LoadCustomers).
It acts as the intermediary ( glue) between the view and model.
The view model retrieves data from the model and exposes it to the view as
properties in a form that the view can easily digest.
10. MVVM Benefits
As with other separation patterns such as MVC, MVVM facilitates the
separation of concerns.
The advantages of separating concerns in the MVVM manner include the
facilitation of the following:
Developer/Designer Collaboration without Conflict
Testable Code
Code Maintainability
11. 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.
http://knockoutjs.com
13. Headline features
Elegant dependency tracking - automatically updates the right parts of your UI
whenever your data model changes.
Declarative bindings - a simple and obvious way to connect parts of your UI to
your data model. You can construct a complex dynamic UIs easily using
arbitrarily nested binding contexts.
Trivially extensible - implement custom behaviors as new declarative bindings
for easy reuse in just a few lines of code.
Compact - around 13kb after gzipping
14. Headline features
Pure JavaScript library - works with any server or client-side technology
Can be added on top of your existing web application without requiring major
architectural changes
Works on any mainstream browser (IE 6+, Firefox 2+, Chrome, Safari, others)
Open source
Great community
15. Bindings
Data-bind attributes in html
ko.observable() for the properties
ko.computed() for mixes between properties and/or strings
ko.applyBindings() to activate bindings
16. Simple Binding Example
<div data-bind=“text: message”></div>
function viewModel () {
this.message: ko.obersvable(“Hello World”);
}
ko.applyBindings(viewModel);
18. Bindings
Observable is a function !
Do not to this:
viewModel.message = ‘hi’;
Do this:
viewModel.message(‘hi’);
19. Most used bindings
Text
Today's message is: <span data-bind="text: myMessage"></span>
Value
Today's message is: <input type=‘text’ data-bind=“value: myMessage“/>
Html
<div data-bind="html: news"></div>
25. Form Fields Bindings - submit
<form data-bind="submit: doSomething">
... form contents go here ...
<button type="submit">Submit</button>
</form>
var viewModel = {
doSomething : function(formElement) {
// ... now do something
}
};
26. Form Fields Bindings - enable
<p>
<input type='checkbox' data-bind="checked: hasCellphone" />
<span> I have a cellphone </span>
</p>
<p> Your cellphone number:
<input type='text' data-bind="value: cellNumber,
enable: hasCellphone" />
</p>
var viewModel = {
hasCellphone : ko.observable(false),
cellNumber: ko.observable(“”)
};
27. Form Fields Bindings - hasFocus
<input data-bind="hasFocus: isSelected" />
<span data-bind="visible: isSelected">The textbox has focus</span>
var viewModel = {
isSelected: ko.observable(false),
setIsSelected: function() {
this.isSelected(true)
}
};
28. Form Fields Bindings - checked
<p>Send me spam:
<input type="checkbox" data-bind="checked: wantsSpam" />
</p>
var viewModel = {
wantsSpam: ko.observable(true) // Initially checked
};
// ... then later ...
viewModel.wantsSpam(false); // The checkbox becomes unchecked
29. Form Fields Bindings – checked
<div data-bind="visible: wantsSpam"> Preferred flavor of spam:
<div>
<input type="radio" name=“group" value="cherry" data-bind="checked: spamFlavor" /> Cherry
</div>
<div>
<input type="radio" name=“group" value="almond" data-bind="checked: spamFlavor" /> Almond
</div>
</div>
var viewModel = {
wantsSpam: ko.observable(true),
spamFlavor: ko.observable("almond") // selects only the Almond radio button
};
viewModel.spamFlavor("cherry"); // Now only Cherry radio button is checked
30. Form Fields Bindings - options
<span>Destination country: </span>
<select data-bind="options: availableCountries"></select>
var viewModel = {
// These are the initial options
availableCountries: ko.observableArray(['France', 'Spain'])
};
// ... then later ...
viewModel.availableCountries.push('China'); // Adds another option
31. Templates
There are two main ways of using templates: native and string based
Native templating is the mechanism that underpins foreach, if, with, and other
control flow bindings.
Internally, those control flow bindings capture the HTML markup contained in
your element, and use it as a template to render against an arbitrary data item.
This feature is built into Knockout and doesn’t require any external library.
33. Templates
String-based templating is a way to connect Knockout to a third-party
template engine.
Knockout will pass your model values to the external template engine and
inject the resulting markup string into your document.
35. Mapping
All properties of an object are converted into an observable. If an update would
change the value, it will update the observable.
Arrays are converted into observable arrays. If an update would change the
number of items, it will perform the appropriate add/remove actions
var viewModel = ko.mapping.fromJS(data);
// Every time data is received from the server:
ko.mapping.fromJS(data, viewModel);
36. Unmapping
If you want to convert your mapped object back to a regular JS object, use:
var unmapped = ko.mapping.toJS(viewModel);
The mapping and unmapping will also try to keep the order the same as the
original JavaScript array/ observableArray.
38. Navigation
You can implement navigation with Sammy JS ( for example)
http://learn.knockoutjs.com/#/?tutorial=webmail
39. Validation
You can use Knockout Validation ( for example):
https://github.com/Knockout-Contrib/Knockout-Validation
Support for :
required, min , max, minLenght,
maxLenght, email, pattern, step, date,
number, digit, date, equal, not eqal
http://jsfiddle.net/slown1/bzkE5/2/
40. Testing
You can use Jasmine and Phantom JS ( for example):
http://kylehodgson.com/2012/11/29/knockoutjs-and-testing/
describe("Person Name", function() {
it("computes fullName based on firstName and lastName",
function() {
var target = new PersonNameViewModel("Ada","Lovelace");
expect(target.fullName()).toBe("Ada Lovelace");
});
});
41. Let’s see some code
My Demo
http://193.226.9.134:8000/MobileServicesWebDemo/
42. Conclusions
Elegant dependency tracking
Declarative bindings
Trivially extensible
Pure JavaScript library
Can be added on top of your existing web application
Works on any mainstream browser Open source
Great community
Developer/Designer
Collaboration without Conflict
Testable Code