Fundaments of Knockout js

44
Fundamentals of Knockout JS 26 march 2014, Timisoara

description

In this presentation you will learn the basics of knockout and make a deep dive by building a chat app.

Transcript of Fundaments of Knockout js

Page 1: Fundaments of Knockout js

Fundamentals of Knockout JS

26 march 2014, Timisoara

Page 2: Fundaments of Knockout js

Flavius-Radu DemianSoftware 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

[email protected] | [email protected] | @slowarad

Page 3: Fundaments of Knockout js

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

Page 4: Fundaments of Knockout js

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

Page 5: Fundaments of Knockout js

Agenda

The MVVM Pattern Welcome to KnockoutHeadline FeaturesBindingsTemplates Mapping and unmappingNavigationTestingSamplesConclusions

Page 6: Fundaments of Knockout js

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.

Page 7: Fundaments of Knockout js

What is MVVM - Model

The Model encapsulates the domain model, business logic and may include data access.

User{

username,firstname,lastname,email

}

Page 8: Fundaments of Knockout js

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.

Page 9: Fundaments of Knockout js

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.

Page 10: Fundaments of Knockout js

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

Page 11: Fundaments of Knockout js

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

Page 13: Fundaments of Knockout js

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

Page 14: Fundaments of Knockout js

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

Page 15: Fundaments of Knockout js

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

Page 16: Fundaments of Knockout js

Simple Binding Example

<div data-bind=“text: message”></div>

function viewModel () {this.message: ko.obersvable(“Hello World”);

}

ko.applyBindings(viewModel);

Page 17: Fundaments of Knockout js

Bindings

Page 18: Fundaments of Knockout js

Bindings

Observable is a function !

Do not to this:

viewModel.message = ‘hi’;

Do this:

viewModel.message(‘hi’);

Page 19: Fundaments of Knockout js

Most used bindings

TextToday's message is: <span data-bind="text: myMessage"></span>

ValueToday's message is: <input type=‘text’ data-bind=“value: myMessage“/>

Html<div data-bind="html: news"></div>

Page 20: Fundaments of Knockout js

Most used bindings

Css<p data-bind="css: sendByMe == false ? 'bubbleLeft' : 'bubbleRight‘ ”></p> Style<p data-bind="style: { color: value < 0 ? 'red' : 'black' }"></p>

Attr<a data-bind="attr: { href: url, title: title}">Custom Link</a>

Page 21: Fundaments of Knockout js

Control Flow Bindings - foreach

<ul data-bind="foreach: people“><li> <p data-bind="text: firstName"></li><li> <p data-bind="text: lastName"> </li>

</ul>

ko.applyBindings({ people: [ { firstName: 'Bert', lastName: 'Bertington' }, { firstName: 'Charles', lastName: 'Charlesforth' }]

});

Page 22: Fundaments of Knockout js

Control Flow Bindings - If

<ul data-bind="foreach: planets"> <li>Planet: <b data-bind="text: name"> </b> <div data-bind="if: capital"> Capital: <b data-bind="text: capital.cityName"> </b></div>

</li></ul>

ko.applyBindings({ planets: [ { name: 'Mercury', capital: null }, { name: 'Earth', capital: { cityName: 'Barnsley' } } ]

});

Page 23: Fundaments of Knockout js

Form Fields Bindings - click

You've clicked <span data-bind="text: numberOfClicks"></span> times <button data-bind="click: incrementClickCounter">Click me</button>

var viewModel = { numberOfClicks : ko.observable(0), incrementClickCounter : function() { var previousCount = this.numberOfClicks(); this.numberOfClicks(previousCount + 1); } };

Page 24: Fundaments of Knockout js

Form Fields Bindings - event

<div data-bind="event: { mouseover: showDetails, mouseout: hideDetails }"> Mouse over me </div> <div data-bind="visible: detailsShown "> Details </div>

var viewModel = { detailsShown: ko.observable(false), showDetails: function() { this.detailsShown(true); }, hideDetails: function() { this.detailsShown(false); } };

Page 25: Fundaments of Knockout js

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 } };

Page 26: Fundaments of Knockout js

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(“”) };

Page 27: Fundaments of Knockout js

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)

}};

Page 28: Fundaments of Knockout js

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

Page 29: Fundaments of Knockout js

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

Page 30: Fundaments of Knockout js

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

Page 31: Fundaments of Knockout js

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.

Page 32: Fundaments of Knockout js

Native named template example

Page 33: Fundaments of Knockout js

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.

Page 34: Fundaments of Knockout js

String-based Templates

Jquery.tmpl

Page 35: Fundaments of Knockout js

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);

Page 36: Fundaments of Knockout js

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.

Page 37: Fundaments of Knockout js

Helpers

ko.utils.arrayFirstko.utils. arrayFilterko.utils.arrayForEachko.utils.arrayGetDistinctValuesko.utils.arrayIndexOfko.utils.arrayPushAllko.utils.unwrapObservableunshift – insert at the beggining, shift – removes the first element, reverse, sort, splice, sliceand lots more…

Page 38: Fundaments of Knockout js

Navigation

You can implement navigation with Sammy JS ( for example)

http://learn.knockoutjs.com/#/?tutorial=webmail

Page 39: Fundaments of Knockout js

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/

Page 40: Fundaments of Knockout js

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"); }); });

Page 41: Fundaments of Knockout js

Let’s see some code

My Demo

http://193.226.9.134:8000/MobileServicesWebDemo/

Page 42: Fundaments of Knockout js

Conclusions

Elegant dependency trackingDeclarative bindings Trivially extensiblePure JavaScript libraryCan be added on top of your existing web applicationWorks on any mainstream browser Open sourceGreat communityDeveloper/Designer Collaboration without ConflictTestable Code

Page 43: Fundaments of Knockout js

Thanks